diff --git a/TRY-IT.md b/TRY-IT.md index d58231f..ac0b760 100644 --- a/TRY-IT.md +++ b/TRY-IT.md @@ -123,6 +123,7 @@ qqq widget get SampleStackedBarChartWidget --output json # the raw payload qqq prefs list ; qqq prefs get regional ; qqq prefs set regional --set weekStartsOn=MONDAY qqq help-search person ; qqq report run --format xlsx qqq search Avery ; qqq tail +qqq extensions ; qqq esb table person # extensions (qbits): see "Extensions (qbits)" below ``` Profiles name servers, as `aws --profile`; sign-ins live in the OS keyring (macOS Keychain here, Secret Service on @@ -227,6 +228,67 @@ durable-jobs server, TABLE_BASED sign-in. Built but not verifiable against this saved views, server-side column statistics (columnStats), audits, a variant-backed table, exposed joins (joins were checked through an association join instead); node tests and a local stub server cover those. +## Extensions (qbits) + +An extension is a qbit or module that adds UI API operations. The CLI knows every extension whose +document was merged into the client (13 today, listed in `docs/extensions.md`); a server installs +some of them and lists them in `GET /version`. Each has a noun: + +| Noun | Extension | First-class verbs | Generated verbs (one per operation) | +|---|---|---|---| +| `qqq esb` | esb (qqq) | `overview`, `table `, `process

`, `dead-letters `, `messages [--trigger t]` | `get-overview`, `get-table`, ... | +| `qqq collab` | collaboration | `presence [pk] [--watch\|--observe]`, `comments list\|add`, `favorites list\|add\|remove`, `recents`, `follow [--status]`, `unfollow`, `my-work`, `people [q]` | `get-records-timeline
`, `get-records-tags`, `put-records-assignment`, ... (45) | +| `qqq health`, `alerts`, `assistant`, `data-analysis`, `db-performance`, `edi`, `qa-capture`, `quick-search`, `release-notes`, `secured-data`, `sql-workbench` | the qbit of that name | none yet | every operation, e.g. `qqq sql-workbench get-capabilities` | + +Generated verbs are the method plus the literal path segments after the extension's prefix. They take +path parameters as arguments or `--path name=value`, plus `--param`, `--body-json`, `--form` and `--out`. +`qqq --help` lists them with the operation behind each. + +What happens: + +- **Installed.** The command runs. `qqq whoami` and `qqq extensions` show it with its version. +- **Not installed.** Every verb of the noun, and `qqq api ` for any of its operations, stops + before calling the server, with exit 5: `extension collaboration is not installed on this server + (installed: esb 1.1.0)`. +- **Installed below the minimum the client needs** (esb, health and collaboration need 1.1.0): exit 5, + `this client needs extension esb 1.1.0 or later; this server has 1.0.0`. +- **Installed but unknown to this client** (a newer qbit): listed by `qqq whoami` and `qqq extensions` + as `unknown to this client`, never dropped. It has no noun until the client document is regenerated. + +The installed list comes from `GET /version`, cached with the metadata for five minutes (`qqq cache +refresh` rereads it). `QQQ_EXTENSION_CHECK=off` skips the check, for a Prism mock whose `/version` is +only an example. + +```sh +qqq extensions # known vs installed, versions, minimums, operations +qqq api --list --extension collaboration # an extension's operations (the list has an extension column) +qqq esb table person # sample server: what person publishes, which processes it triggers +qqq esb process syncPerson ; qqq esb messages personEvents --trigger syncPerson.personEvents +qqq collab presence person 1 # sample server: exit 5, collaboration is not installed +``` + +Collaboration needs a server with qbit-collaboration. Its repo has a demo server (memory backend, MOCK +users alice, bob and admin); it runs on port 8098 beside the sample server: + +```sh +cd ../qbit-collaboration && ./mvnw -q test-compile dependency:build-classpath -Dmdep.includeScope=test -Dmdep.outputFile=target/demo-classpath.txt +mkdir -p /tmp/fe/next-dashboard && echo '' > /tmp/fe/next-dashboard/index.html # it insists on a Next export +java -Dqqq.javalin.frontend=next -Dcollab.dev.port=8098 -cp "target/test-classes:target/classes:$(cat target/demo-classpath.txt):/tmp/fe" \ + com.kingsrook.qbits.collaboration.devserver.CollaborationDevServer + +qqq login --server http://localhost:8098 --profile collab # alice +qqq --profile collab collab presence person 1 --watch # join; prints each change until Ctrl+C +qqq --profile collab collab presence person --observe # watch the table without appearing +qqq --profile collab collab comments list person 1 ; qqq --profile collab collab comments add person 1 "Looks right" +qqq --profile collab collab favorites list ; qqq --profile collab collab favorites add person 4 +qqq --profile collab collab follow person 2 --comments off ; qqq --profile collab collab my-work +``` + +To see someone else, open `http://localhost:8098/?createMockSession=true&user=bob` in a browser on a +person (needs a real Next export), or hold a lease as bob with curl (`POST /qqq/v1/qbit/collaboration/presence?user=bob`). +Presence lists everyone holding a lease on the record or table, you included while you `--watch`; +`since` is when the CLI first saw them. + ## Reporting what you find Say which screen, what you pressed, what you expected. If the TUI crashes, the terminal should be restored; diff --git a/docs/extensions.md b/docs/extensions.md new file mode 100644 index 0000000..902819b --- /dev/null +++ b/docs/extensions.md @@ -0,0 +1,37 @@ +# Extension documents in the client + +The client document (`packages/ui-api-client/openapi/qqq-v1.json`) is the sample server's live +document for core (QQQ 4.1.0-SNAPSHOT, `develop` 6ac64fc66, UI API 1.8.0, which already carries esb) +merged with the extension document each repository commits at `src/main/resources/openapi/qqq-v1/`. +Rebuild it with the sample server running: + +```sh +npm run spec:merge-extensions && npm run generate # writes openapi/extension-sources.json too +``` + +Versions merged on 2026-10-31 (machine-readable copy: `packages/ui-api-client/openapi/extension-sources.json`): + +| Extension | Version | Prefix | Operations | Repository at | Minimum the client needs | +|---|---|---|---|---|---| +| esb | 1.1.0 | `/esb` | 5 | qqq `develop` 6ac64fc66 (qqq-esb) | 1.1.0 (operationIds, UI-API-CHANGELOG) | +| health | 1.1.0 | `/health` | 4 | qqq `develop` 6ac64fc66 (qqq-middleware-javalin) | 1.1.0 (same) | +| alerts | 1.2.0 | `/alerts` | 6 | qbit-alerts `develop` a3fc6ac | | +| assistant | 1.6.0 | `/assistant` | 16 | qbit-assistant `develop` bcf173f | | +| collaboration | 1.1.0 | `/qbit/collaboration` | 45 | qbit-collaboration `develop` 03407ae | 1.1.0 (presence schemas, error contract) | +| data-analysis | 1.5.0 | `/qbit/data-analysis` | 21 | qbit-data-analysis `develop` 368d2c0 | | +| db-performance | 1.0.0 | `/qbit/db-performance` | 4 | qbit-db-performance `develop` 4fd2c30 | | +| edi | 1.1.0 | `/qbit/edi` | 4 | qbit-edi `develop` 75a4e6b | | +| qa-capture | 1.0.0 | `/qbit/qa-capture` | 2 | qbit-qa-capture `develop` 1aee6cb | | +| quick-search | 1.1.0 | `/qbit/quick-search` | 2 | qbit-quick-search `develop` bd50e1f | | +| release-notes | 1.0.0 | `/qbit/release-notes` | 3 | qbit-release-notes `develop` 8fed18e | | +| secured-data | 1.1.0 | `/qbit/secured-data` | 3 | qbit-secured-data `develop` 7b302ed | | +| sql-workbench | 1.1.0 | `/sql-workbench` | 21 | qbit-sql-workbench `develop` a182076 | | + +202 operations in all, 136 from extensions. No extension document conflicted with core or another +(identical shared schemas such as `BasicErrorResponseV1`). There is no `qbit-middleware-health`: the +health extension lives in qqq's `qqq-middleware-javalin`. Other qbits in the workspace (authentik, +jobs, help, middleware-mcp, ...) register no UI API extension. + +Minimums are only set where an extension's own docs state one; the rest accept any version the +server lists. Each extension's minimum and realtime channels live in +`packages/core/src/extensions/registry.ts` (`FACTS`). diff --git a/docs/parity/feature-matrix.md b/docs/parity/feature-matrix.md index 8828c66..b20a417 100644 --- a/docs/parity/feature-matrix.md +++ b/docs/parity/feature-matrix.md @@ -273,7 +273,7 @@ The TUI column fills in during M3. | REC-062 | Inline enum possible values filter by label prefix without a lookup request; CHIP adornments style options and | pass | todo | inline enums | | REC-060 | Material table and field form adjusters and field rules operate against the real QQQ sample server | todo | todo | adjusters wired, no sample to test | | REC-064 | Record sections render qualified fields from readable exposed joins | partial | todo | table get --join adds joined fields (queryJoins); verified with an association join | -| REC-063 | Record view, edit and copy load from the table variant selected on the query screen | partial | todo | get, copy and update -i read with --variant; v1 writes ignore it (server finding #18) | +| REC-063 | Record view, edit and copy load from the table variant selected on the query screen | partial | todo | get, copy and update -i read with --variant; v1 writes ignore it (server finding #19) | | REC-065 | Unchanged DATE_TIME instants and precision survive edit and copy | pass | todo | an unchanged wall-clock time keeps the original instant and its precision | | SEC-001 | Table hidden from a user (DenyBehavior.HIDDEN): absent from navigation, direct link loads nothing, backend ref | pass | todo | | | SEC-002 | Table disabled for a user (DenyBehavior.DISABLED): listed, but list/record/create/edit links explain the denia | todo | todo | disabled tables listed with a reason | diff --git a/docs/server-findings.md b/docs/server-findings.md index 413668d..f574088 100644 --- a/docs/server-findings.md +++ b/docs/server-findings.md @@ -22,5 +22,6 @@ the sample app and MOCK authentication. Each is a candidate issue for `QRun-IO/q | 15 | A step that fails on missing input answers `ERROR` with only `error` (`Error message: Unable to get Cities by state. Missing required input.`), no `userFacingError`, and the field is not marked required in the step metadata, so a client cannot tell an input problem from a crash or ask for the field first. | `qqq process run placeAddressPick --no-prompt`. | The CLI exits 6 (validation) when the message says required input is missing or the error is user-facing, 1 otherwise. Mark the fields required, or return `userFacingError` (or a 400 with `fieldErrors`). | | 16 | `downloadRecordFieldFile` on a BLOB field without adornments answers 500 `NullPointerException (Cannot invoke "java.util.List.stream()" because the return value of "QFieldMetaData.getAdornments()" is null)`. | `qqq table create fieldLab --set name=x --upload blobValue=./a.txt`, then `qqq api downloadRecordFieldFile --path tableName=fieldLab --path primaryKey= --path fieldName=blobValue --path filename=a.txt -o out`. | `qqq table download` uses the route only for FILE_DOWNLOAD fields and decodes the record's base64 BLOB value otherwise. The route should treat no adornments as none (or answer 404/400). | | 17 | The sample app declares no field adornments other than LINK, no hidden fields or sections, no help content, no exposed joins, no composite or aliased associations and no table the mock user may not read, so CHIP, REVEAL, RENDER_HTML, CODE_EDITOR, ERROR, FILE_DOWNLOAD, WIDGET, TOOLTIP, help display, denied child reads and composite associations can only be checked with unit tests against the client. | `GET /metaData/table/{t}` for every sample table. | None needed in the client; a `fieldLab`-style adornment table in the sample (one field per adornment, a hidden section, help on a field, section and table, a composite association) would make these rows checkable live. | -| 18 | The v1 insert, update and delete routes do not read a table variant: `TableInsertExecutor`, `TableUpdateExecutor` and `TableDeleteExecutor` never call `ExecutorSessionUtils.setTableVariantInSession`, and the spec gives them no `tableVariant` (query, count, get, export and the process routes have it). A client cannot write to a variant-backed table over v1. | Read `executors/Table{Insert,Update,Delete}Executor.java`; the legacy `QJavalinImplementation.setupSession` read a `tableVariant` form or query parameter for every route. | `qqq table create/update/delete/copy --variant` send `tableVariant` as a query parameter (as the get route takes it) and say the server may ignore it. Add the parameter to the three routes. | -| 19 | Joins do not reach the export route: `exportTable` has no `joins` member and a joined name in `fieldNames` (`pet.name` on `person`, a join the query route accepts) answers 500 `Field name pet.name was not found on the Person table.` The web UI exports joined columns by name; unclear whether exposed joins work there. | `qqq api exportTable --path tableName=person --body-json '{"format":"csv","fieldNames":["id","pet.name"]}'` | `qqq table export` accepts joined columns of exposed joins only and checks them before sending. | +| 18 | qbit-collaboration 1.1.0: when the last viewer leaves, `presence.changed` (and the table snapshot) is `{"table":"person"}` with no `viewers`, although `CollaborationPresenceSnapshotV1.viewers` is a non-nullable array. A client that waits for `viewers` keeps showing the last person. Seen on the qbit's `CollaborationDevServer` (QQQ 4.1.0-RC.15). | Two sessions (`?user=bob` and alice); bob POSTs then DELETEs `/qbit/collaboration/presence` while alice is subscribed to `table:person`. | The kernel treats a payload with `table` as the snapshot and missing `viewers` as none. The qbit should send `"viewers": []`. | +| 19 | The v1 insert, update and delete routes do not read a table variant: `TableInsertExecutor`, `TableUpdateExecutor` and `TableDeleteExecutor` never call `ExecutorSessionUtils.setTableVariantInSession`, and the spec gives them no `tableVariant` (query, count, get, export and the process routes have it). A client cannot write to a variant-backed table over v1. | Read `executors/Table{Insert,Update,Delete}Executor.java`; the legacy `QJavalinImplementation.setupSession` read a `tableVariant` form or query parameter for every route. | `qqq table create/update/delete/copy --variant` send `tableVariant` as a query parameter (as the get route takes it) and say the server may ignore it. Add the parameter to the three routes. | +| 20 | Joins do not reach the export route: `exportTable` has no `joins` member and a joined name in `fieldNames` (`pet.name` on `person`, a join the query route accepts) answers 500 `Field name pet.name was not found on the Person table.` The web UI exports joined columns by name; unclear whether exposed joins work there. | `qqq api exportTable --path tableName=person --body-json '{"format":"csv","fieldNames":["id","pet.name"]}'` | `qqq table export` accepts joined columns of exposed joins only and checks them before sending. | diff --git a/package.json b/package.json index 22a0a64..bbf6e69 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ ], "scripts": { "spec:merge": "node scripts/merge-spec.mjs --out packages/ui-api-client/openapi/qqq-v1.json", + "spec:merge-extensions": "node scripts/merge-extensions.mjs", "generate": "npm run generate -w @qrun-io/qqq-ui-api-client && node scripts/gen-operations.mjs", "build": "npm run build -w @qrun-io/qqq-ui-api-client && npm run build -w @qrun-io/qqq-core && npm run build -w @qrun-io/qqq-ui-api-conformance && npm run build -w @qrun-io/qqq-cli", "test": "npm test --workspaces --if-present", diff --git a/packages/cli/src/commands/api.ts b/packages/cli/src/commands/api.ts index 5dd964e..468669a 100644 --- a/packages/cli/src/commands/api.ts +++ b/packages/cli/src/commands/api.ts @@ -6,7 +6,7 @@ import { readFileSync, writeFileSync } from 'node:fs' import { basename } from 'node:path' import type { Command } from 'commander' -import { OPERATIONS, operation } from '@qrun-io/qqq-core' +import { OPERATIONS, operation, type OperationInfo } from '@qrun-io/qqq-core' import type { Context } from '../context.js' import { UsageError } from '../context.js' import { parsePairs, readJson } from './shared.js' @@ -21,39 +21,62 @@ export function registerApi(program: Command, ctx: () => Context): void { .option('--bytes ', 'raw request body (application/octet-stream)') .option('-o, --out ', 'write a binary response to a file') .option('-l, --list', 'list the operations instead of calling one') - .action(async (operationId: string | undefined, options: { path?: string[]; param?: string[]; bodyJson?: string; form?: string[]; bytes?: string; out?: string; list?: boolean }) => { + .option('-e, --extension ', 'with --list: only this extension\'s operations (`core` for core ones)') + .action(async (operationId: string | undefined, options: OperationOptions & { list?: boolean; extension?: string }) => { const c = ctx() if (options.list || !operationId) { - const rows = OPERATIONS.map((o) => ({ operationId: o.id, method: o.method, path: o.path, body: o.bodyTypes.join('|'), summary: o.summary })) - c.print({ data: rows, columns: ['operationId', 'method', 'path', 'body'], footer: `(${rows.length} operations; qqq api --path k=v --param k=v --body-json '{...}')` }) + const selected = OPERATIONS.filter((o) => !options.extension || (options.extension === 'core' ? !o.extension : o.extension === options.extension)) + const rows = selected.map((o) => ({ operationId: o.id, extension: o.extension ?? '', method: o.method, path: o.path, body: o.bodyTypes.join('|'), summary: o.summary })) + const extensions = new Set(selected.map((o) => o.extension).filter(Boolean)).size + c.print({ data: rows, columns: ['operationId', 'extension', 'method', 'path', 'body'], footer: `(${rows.length} operations, ${extensions} extensions; qqq api --path k=v --param k=v --body-json '{...}'; whether an extension is installed: qqq whoami)` }) return } const op = operation(operationId) if (!op) throw new UsageError(`No operation "${operationId}"; \`qqq api --list\` shows them.`) - let form: Record | undefined - if (options.form) { - form = {} - for (const [k, v] of Object.entries(parsePairs(options.form, '--form'))) { - form[k] = v.startsWith('@') ? new File([readFileSync(v.slice(1))], basename(v.slice(1))) : v - } - } - const result = await c.call(operationId, { - path: parsePairs(options.path, '--path'), - query: parsePairs(options.param, '--param'), - json: options.bodyJson !== undefined ? readJson(options.bodyJson, '--body-json') : undefined, - form, - bytes: options.bytes ? new Uint8Array(readFileSync(options.bytes)) : undefined, - }) - if (result.bytes) { - if (!options.out) throw new UsageError(`${operationId} returned ${result.contentType} (${result.bytes.length} bytes); pass --out `) - writeFileSync(options.out, result.bytes) - c.note(`wrote ${options.out} (${result.bytes.length} bytes, ${result.contentType})`) - return - } - if (typeof result.data === 'string') { - process.stdout.write(result.data.endsWith('\n') ? result.data : result.data + '\n') - return - } - c.print({ data: result.data }) + await runOperation(c, op, options) }) } + +/** The options every generic operation command takes. */ +export interface OperationOptions { + path?: string[] + param?: string[] + bodyJson?: string + form?: string[] + bytes?: string + out?: string +} + +/** + * Calls one operation from command options and prints the result. An operation of an extension + * the server does not list is refused before the request (ExtensionNotInstalledError, exit 5). + */ +export async function runOperation(c: Context, op: OperationInfo, options: OperationOptions, pathValues: Record = {}): Promise { + if (op.extension) (await c.extensions()).requireOperation(op.id) + const operationId = op.id + let form: Record | undefined + if (options.form) { + form = {} + for (const [k, v] of Object.entries(parsePairs(options.form, '--form'))) { + form[k] = v.startsWith('@') ? new File([readFileSync(v.slice(1))], basename(v.slice(1))) : v + } + } + const result = await c.call(operationId, { + path: { ...pathValues, ...parsePairs(options.path, '--path') }, + query: parsePairs(options.param, '--param'), + json: options.bodyJson !== undefined ? readJson(options.bodyJson, '--body-json') : undefined, + form, + bytes: options.bytes ? new Uint8Array(readFileSync(options.bytes)) : undefined, + }) + if (result.bytes) { + if (!options.out) throw new UsageError(`${operationId} returned ${result.contentType} (${result.bytes.length} bytes); pass --out `) + writeFileSync(options.out, result.bytes) + c.note(`wrote ${options.out} (${result.bytes.length} bytes, ${result.contentType})`) + return + } + if (typeof result.data === 'string') { + process.stdout.write(result.data.endsWith('\n') ? result.data : result.data + '\n') + return + } + c.print({ data: result.data }) +} diff --git a/packages/cli/src/commands/auth.ts b/packages/cli/src/commands/auth.ts index 7cc42fd..8704237 100644 --- a/packages/cli/src/commands/auth.ts +++ b/packages/cli/src/commands/auth.ts @@ -78,7 +78,7 @@ export function registerAuth(program: Command, ctx: () => Context): void { tokenExpires: login && login.kind !== 'session' ? new Date(login.tokens.expiresAt).toISOString() : '', apiVersion: version.apiVersion, features: ((version.features ?? []) as string[]).join(', '), - extensions: ((version.extensions ?? []) as Json[]).map((e) => `${e.name} ${e.version}`).join(', '), + extensions: (await c.extensions({ refresh: true })).describe(), apps: Object.keys((metaData.apps ?? {}) as Json).length, tables: Object.keys((metaData.tables ?? {}) as Json).length, processes: Object.keys((metaData.processes ?? {}) as Json).length, diff --git a/packages/cli/src/commands/collab.ts b/packages/cli/src/commands/collab.ts new file mode 100644 index 0000000..7c8bd10 --- /dev/null +++ b/packages/cli/src/commands/collab.ts @@ -0,0 +1,213 @@ +/* + * Copyright 2026 QRun.IO, Inc. + * Licensed under the Apache License, Version 2.0 (see LICENSE). + */ + +/** + * First-class commands of `qqq collab` (the collaboration extension): presence, comments, + * favorites, recents, follow, my work and people. The kernel's Collaboration module does the + * calls; every command requires the extension first (exit 5 with the installed list). + */ + +import type { Command } from 'commander' +import { COLLABORATION, type CollaborationTarget, type CommentEntry, type FavoriteEntry, type PresenceState } from '@qrun-io/qqq-core' +import type { Context } from '../context.js' +import { UsageError } from '../context.js' +import type { Json } from './shared.js' + +const TARGET_TYPES = ['TABLE', 'APP', 'RECORD', 'PROCESS', 'REPORT', 'SAVED_VIEW'] + +async function collab(c: Context) { + ;(await c.extensions()).require(COLLABORATION) + return c.collaboration() +} + +function hhmmss(date: Date): string { + return date.toTimeString().slice(0, 8) +} + +/** `2 here: Alice Morgan (viewing since 17:50:01), Bob Chen (editing email since 17:51:10)`. */ +export function presenceLine(state: PresenceState): string { + if (!state.available) return 'presence: the collaboration extension is not installed' + if (state.error) return `presence: ${state.error}` + const where = state.scope.pk !== undefined ? `${state.scope.table} ${state.scope.pk}` : state.scope.table + if (!state.count) return `nobody on ${where}` + const people = state.people.map((p) => `${p.name} (${String(p.mode).toLowerCase()}${p.fieldName ? ` ${p.fieldName}` : ''} since ${hhmmss(p.since)})`) + return `${state.count} on ${where}: ${people.join(', ')}` +} + +function favoriteRows(items: FavoriteEntry[]): Json[] { + return items.map((f) => ({ id: f.id ?? '', type: f.targetType ?? '', name: f.targetName ?? '', record: f.recordId ?? '', label: f.label ?? '', folder: f.folder ?? '', available: f.available ?? '', href: f.href ?? '' })) +} + +function commentRows(threads: CommentEntry[]): Json[] { + const rows: Json[] = [] + const add = (comment: CommentEntry, depth: number) => { + rows.push({ + id: comment.id ?? '', + author: comment.authorDisplayName ?? comment.authorUserId ?? '', + at: String(comment.createdAt ?? '').slice(0, 16).replace('T', ' '), + state: comment.deleted ? 'deleted' : comment.resolvedAt ? 'resolved' : '', + body: `${depth ? ' > ' : ''}${String(comment.body ?? '').replace(/\s+/g, ' ').slice(0, 100)}`, + }) + for (const reply of comment.replies ?? []) add(reply, depth + 1) + } + for (const thread of threads) add(thread, 0) + return rows +} + +/** `favorites add person 1` is a RECORD; `favorites add person` a TABLE; --type for the rest. */ +function targetOf(name: string, recordId: string | undefined, type: string | undefined): CollaborationTarget { + const targetType = (type ?? (recordId !== undefined ? 'RECORD' : 'TABLE')).toUpperCase() + if (!TARGET_TYPES.includes(targetType)) throw new UsageError(`--type must be one of ${TARGET_TYPES.join(', ')}`) + if (targetType === 'RECORD' && recordId === undefined) throw new UsageError('A RECORD favorite needs the record id: favorites add
') + return { targetType: targetType as CollaborationTarget['targetType'], targetName: name, ...(targetType === 'RECORD' ? { recordId } : {}) } +} + +export function registerCollab(noun: Command, ctx: () => Context): void { + noun.command('presence
[pk]') + .description('Who is on a table or record right now. --watch joins (you appear too) and prints each change until Ctrl+C; --observe watches without joining.') + .option('-w, --watch', 'join and follow changes (heartbeat every 20 s, leaves on exit)') + .option('--observe', 'follow changes without joining') + .option('--editing [field]', 'with --watch: join as EDITING, optionally on a field') + .action(async (table: string, pk: string | undefined, options: { watch?: boolean; observe?: boolean; editing?: string | boolean }) => { + const c = ctx() + const collaboration = await collab(c) + const scope = { table, pk } + const json = c.format === 'json' || c.format === 'yaml' + const emit = (state: PresenceState) => { + if (json) process.stdout.write(JSON.stringify({ ...state, people: state.people.map((p) => ({ ...p, since: p.since.toISOString() })) }) + '\n') + else process.stdout.write(`${hhmmss(new Date())} ${presenceLine(state)}${state.live ? '' : ' (polling)'}\n`) + } + if (!options.watch && !options.observe) { + const state = await collaboration.presenceSnapshot(scope) + const rows = state.people.map((p) => ({ name: p.name, user: p.userId, mode: p.mode, field: p.fieldName ?? '' })) + c.print({ data: { table, pk: pk ?? null, count: state.count, viewers: rows }, rows, columns: ['name', 'user', 'mode', 'field'], footer: `(${state.count} on ${pk !== undefined ? `${table} ${pk}` : table}; --watch to join and follow)` }) + return + } + let last = '' + const handle = await collaboration.joinPresence(scope, { + announce: Boolean(options.watch), + mode: options.editing ? 'EDITING' : 'VIEWING', + fieldName: typeof options.editing === 'string' ? options.editing : undefined, + onChange: (state) => { + const key = JSON.stringify([state.people.map((p) => [p.userId, p.mode, p.fieldName]), state.error, state.live]) + if (key !== last) { + last = key + emit(state) + } + }, + }) + if (handle.state.error) throw new Error(`presence on ${table}${pk !== undefined ? ` ${pk}` : ''}: ${handle.state.error}`) + if (!json) c.note(options.watch ? 'Joined; Ctrl+C leaves.' : 'Observing; Ctrl+C stops.') + await new Promise((resolve) => { + const leave = () => { + void handle.stop().finally(resolve) + } + process.once('SIGINT', leave) + process.once('SIGTERM', leave) + }) + }) + + const comments = noun.command('comments').description("A record's comment threads.") + comments.command('list
') + .description('Comment threads by latest activity, replies under their thread.') + .option('-l, --limit ', 'threads per page (1-50)', '20') + .option('--cursor ', 'continue from a previous page') + .action(async (table: string, pk: string, options: { limit: string; cursor?: string }) => { + const c = ctx() + const page = await (await collab(c)).comments(table, pk, { limit: Number(options.limit), cursor: options.cursor }) + c.print({ data: page, rows: commentRows(page.threads), columns: ['id', 'author', 'at', 'state', 'body'], footer: `(${page.threads.length} threads${page.nextCursor ? `; more: --cursor ${page.nextCursor}` : ''})` }) + }) + comments.command('add
') + .description('Post a comment (mentions: @[Name](user:id)); --reply-to answers a thread.') + .option('-r, --reply-to ', 'reply to this comment') + .option('--field ', 'anchor the comment on a field') + .action(async (table: string, pk: string, body: string[], options: { replyTo?: string; field?: string }) => { + const c = ctx() + const comment = await (await collab(c)).addComment(table, pk, body.join(' '), { parentCommentId: options.replyTo ? Number(options.replyTo) : undefined, fieldName: options.field }) + c.print({ data: comment, rows: commentRows([comment]), columns: ['id', 'author', 'at', 'state', 'body'] }) + }) + + const favorites = noun.command('favorites').description('Your favorites (starred tables, records, apps, processes, reports, saved views).') + favorites.command('list').description('Your favorites in order.').action(async () => { + const c = ctx() + const items = await (await collab(c)).favorites() + c.print({ data: items, rows: favoriteRows(items), columns: ['id', 'type', 'name', 'record', 'label', 'folder', 'available'] }) + }) + favorites.command('add [recordId]') + .description('Star a record (`add person 1`), a table (`add person`), or --type APP|PROCESS|REPORT|SAVED_VIEW.') + .option('-t, --type ', TARGET_TYPES.join('|')) + .action(async (name: string, recordId: string | undefined, options: { type?: string }) => { + const c = ctx() + const target = targetOf(name, recordId, options.type) + await (await collab(c)).addFavorite(target) + c.print({ data: { starred: target }, rows: [{ starred: `${target.targetType} ${name}${target.recordId ? ` ${target.recordId}` : ''}` }], columns: ['starred'] }) + }) + favorites.command('remove [recordId]') + .description('Unstar a target (same arguments as add).') + .option('-t, --type ', TARGET_TYPES.join('|')) + .action(async (name: string, recordId: string | undefined, options: { type?: string }) => { + const c = ctx() + const target = targetOf(name, recordId, options.type) + await (await collab(c)).removeFavorite(target) + c.print({ data: { unstarred: target }, rows: [{ unstarred: `${target.targetType} ${name}${target.recordId ? ` ${target.recordId}` : ''}` }], columns: ['unstarred'] }) + }) + + noun.command('recents') + .description('What you viewed recently, newest first.') + .option('-l, --limit ', 'most entries (1-50)', '20') + .action(async (options: { limit: string }) => { + const c = ctx() + const items = await (await collab(c)).recents(Number(options.limit)) + c.print({ data: items, rows: favoriteRows(items), columns: ['type', 'name', 'record', 'label', 'available'] }) + }) + + const followRows = (state: { following: boolean; follow?: Json | null }) => [{ following: state.following, notifyOnChange: state.follow?.notifyOnChange ?? '', notifyOnComment: state.follow?.notifyOnComment ?? '', reason: state.follow?.reason ?? '' }] + noun.command('follow
') + .description('Follow a record (notifications on changes and comments); --status only shows the state.') + .option('--status', 'show whether you follow it, change nothing') + .option('--changes ', 'notify on changes') + .option('--comments ', 'notify on comments') + .action(async (table: string, pk: string, options: { status?: boolean; changes?: string; comments?: string }) => { + const c = ctx() + const collaboration = await collab(c) + const flag = (v: string | undefined, name: string) => { + if (v === undefined) return undefined + if (!/^(on|off|true|false)$/i.test(v)) throw new UsageError(`${name} takes on or off`) + return /^(on|true)$/i.test(v) + } + const state = options.status ? await collaboration.followState(table, pk) : await collaboration.follow(table, pk, { notifyOnChange: flag(options.changes, '--changes'), notifyOnComment: flag(options.comments, '--comments') }) + c.print({ data: state, rows: followRows(state as never), columns: ['following', 'notifyOnChange', 'notifyOnComment', 'reason'] }) + }) + noun.command('unfollow
') + .description('Stop following a record.') + .action(async (table: string, pk: string) => { + const c = ctx() + const state = await (await collab(c)).unfollow(table, pk) + c.print({ data: state, rows: followRows(state as never), columns: ['following', 'notifyOnChange', 'notifyOnComment', 'reason'] }) + }) + + noun.command('my-work') + .description('Your open tasks, records assigned to you per table, and unread mentions.') + .action(async () => { + const c = ctx() + const work = await (await collab(c)).myWork() + const rows: Json[] = [ + { item: 'open tasks', value: work.openTaskCount ?? 0 }, + { item: 'unread mentions', value: work.unreadMentionCount ?? 0 }, + ...Object.entries(work.assignedRecordsByTable ?? {}).map(([table, n]) => ({ item: `assigned: ${table}`, value: n })), + ...(work.tasks ?? []).map((t) => ({ item: `task ${t.id ?? ''}${t.dueAt ? ` due ${String(t.dueAt).slice(0, 10)}` : ''}`, value: `${t.title ?? ''}${t.tableName ? ` (${t.tableName} ${t.recordId ?? ''})` : ''}` })), + ] + c.print({ data: work, rows, columns: ['item', 'value'] }) + }) + + noun.command('people [query]') + .description('Search the people directory by name or email.') + .option('-l, --limit ', 'most people (1-100)', '20') + .action(async (query: string | undefined, options: { limit: string }) => { + const c = ctx() + const people = await (await collab(c)).people(query, Number(options.limit)) + c.print({ data: people, rows: people.map((p) => ({ user: p.userId ?? '', name: p.displayName ?? '', email: p.email ?? '', lastSeen: String(p.lastSeenAt ?? '').slice(0, 16).replace('T', ' ') })), columns: ['user', 'name', 'email', 'lastSeen'] }) + }) +} diff --git a/packages/cli/src/commands/extensions.ts b/packages/cli/src/commands/extensions.ts new file mode 100644 index 0000000..21f19c9 --- /dev/null +++ b/packages/cli/src/commands/extensions.ts @@ -0,0 +1,183 @@ +/* + * Copyright 2026 QRun.IO, Inc. + * Licensed under the Apache License, Version 2.0 (see LICENSE). + */ + +/** + * One noun per extension (qbit or module): `qqq esb ...`, `qqq collab ...`, `qqq sql-workbench ...`. + * Every operation of an extension is a subcommand, generated from the operation index + * (`get-overview`, `put-favorites`, `get-records-comments
`), taking its path parameters + * as arguments or --path, plus --param and --body-json. First-class commands (esb, collab) sit next + * to the generated ones. Every subcommand checks the server's GET /version first: an extension that + * is not installed stops with exit 5 and the list of what is installed. + */ + +import type { Command } from 'commander' +import { KNOWN_EXTENSIONS, OPERATIONS, operationsOf, type OperationInfo } from '@qrun-io/qqq-core' +import type { Context } from '../context.js' +import { runOperation, type OperationOptions } from './api.js' +import type { Json } from './shared.js' +import { registerCollab } from './collab.js' + +/** The noun of each extension; the extension's own name unless it is long. */ +export const NOUNS: Record = { collaboration: 'collab' } + +export function nounOf(extension: string): string { + return NOUNS[extension] ?? extension +} + +function kebab(text: string): string { + return text.replace(/([a-z0-9])([A-Z])/g, '$1-$2').replace(/[^A-Za-z0-9]+/g, '-').toLowerCase() +} + +/** + * Subcommand names for an extension's operations: the method and the literal path segments after + * the extension's prefix (`GET /qbit/collaboration/records/{table}/{pk}/comments` is + * `get-records-comments`); names that would collide get `-by-`, then the operationId. + */ +export function subcommandNames(extension: string, pathPrefix: string, operations: OperationInfo[]): Map { + const base = `/qqq/v1${pathPrefix}` + const first = operations.map((op) => { + const segments = op.path.startsWith(base) ? op.path.slice(base.length).split('/').filter(Boolean) : op.path.split('/').filter(Boolean) + const literals = segments.filter((s) => !s.startsWith('{')) + return { op, name: `${op.method.toLowerCase()}-${literals.length ? literals.map(kebab).join('-') : extension}` } + }) + const count = (name: string, list: { name: string }[]) => list.filter((x) => x.name === name).length + const second = first.map((x) => (count(x.name, first) > 1 && x.op.pathParams.length ? { op: x.op, name: `${x.name}-by-${x.op.pathParams.map(kebab).join('-')}` } : x)) + const names = new Map() + for (const x of second) names.set(count(x.name, second) > 1 ? kebab(x.op.id) : x.name, x.op) + return names +} + +/** Adds one generated subcommand per operation of an extension to its noun. */ +export function addOperationCommands(noun: Command, extension: string, pathPrefix: string, ctx: () => Context): void { + const taken = new Set(noun.commands.map((c) => c.name())) + for (const [name, op] of subcommandNames(extension, pathPrefix, operationsOf(extension))) { + if (taken.has(name)) continue + const args = op.pathParams.map((p) => ` [${p}]`).join('') + const cmd = noun.command(`${name}${args}`) + .description(`${op.summary || op.id} (${op.method} ${op.path.replace('/qqq/v1', '')}; operation ${op.id})`) + .option('-p, --path ', 'path parameters (or give them as arguments)') + .option('-q, --param ', `query parameters${op.queryParams.length ? `: ${op.queryParams.join(', ')}` : ''}`) + if (op.bodyTypes.includes('application/json') || op.bodyTypes.length === 0) cmd.option('-b, --body-json ', 'JSON request body (inline, a file, or - for stdin)') + if (op.bodyTypes.includes('multipart/form-data')) cmd.option('-F, --form ', 'multipart form fields; @file uploads a file') + cmd.option('-o, --out ', 'write a binary response to a file') + cmd.action(async (...actionArgs: unknown[]) => { + const values = actionArgs.slice(0, op.pathParams.length) as (string | undefined)[] + const options = actionArgs[op.pathParams.length] as OperationOptions + const pathValues: Record = {} + op.pathParams.forEach((p, i) => { + if (values[i] !== undefined) pathValues[p] = values[i]! + }) + await runOperation(ctx(), op, options, pathValues) + }) + } +} + +/** Requires the extension on the target server (exit 5 with the installed list when it is absent). */ +export async function requireExtension(c: Context, name: string): Promise { + ;(await c.extensions()).require(name) +} + +function counters(destination: Json | undefined): Json { + const c = (destination?.counters ?? {}) as Json + return { published: c.published ?? '', consumed: c.consumed ?? '', failed: c.failed ?? '', deadLettered: c.deadLettered ?? '', inFlight: c.inFlight ?? '', lastActivity: String(c.lastActivity ?? '').slice(0, 19) } +} + +function registerEsb(noun: Command, ctx: () => Context): void { + const run = async (id: string, path: Record = {}, query: Record = {}) => { + const c = ctx() + await requireExtension(c, 'esb') + return { c, data: (await c.call(id, { path, query })).data as Json } + } + const columns = ['role', 'destination', 'type', 'detail', 'state', 'published', 'consumed', 'failed', 'deadLettered', 'inFlight', 'lastActivity'] + const linkRows = (data: Json) => [ + ...((data.publications ?? []) as Json[]).map((p) => { + const d = p.destination as Json | undefined + return { role: 'publishes', destination: d?.name ?? '', type: d?.type ?? '', detail: ((p.events ?? []) as string[]).join(' '), state: '', ...counters(d) } + }), + ...((data.subscribers ?? data.triggers ?? []) as Json[]).map((s) => { + const d = s.destination as Json | undefined + return { role: 'trigger', destination: d?.name ?? '', type: d?.type ?? '', detail: s.processLabel ?? s.processName ?? s.name ?? '', state: s.state ?? '', ...counters(d) } + }), + ] + + noun.command('overview') + .description('Broker connections and every destination with its publishers and triggers (needs ESB permission).') + .action(async () => { + const { c, data } = await run('getEsbOverview') + const rows = ((data.destinations ?? []) as Json[]).map((d) => ({ destination: d.name, type: d.type, provider: d.provider, publishers: ((d.publishers ?? []) as unknown[]).length, triggers: ((d.triggers ?? []) as unknown[]).length, ...counters(d) })) + c.print({ data, rows, columns: ['destination', 'type', 'provider', 'publishers', 'triggers', 'published', 'consumed', 'failed', 'deadLettered', 'lastActivity'], footer: `(${((data.providers ?? []) as unknown[]).length} providers, ${rows.length} destinations)` }) + }) + + noun.command('table
') + .description('What a table publishes and which processes it triggers.') + .action(async (table: string) => { + const { c, data } = await run('getEsbTableByTable', { table }) + c.print({ data, rows: linkRows(data), columns }) + }) + + noun.command('process ') + .description('What a process publishes and what triggers it.') + .action(async (process: string) => { + const { c, data } = await run('getEsbProcessByProcess', { process }) + c.print({ data, rows: linkRows(data), columns }) + }) + + const messageRows = (data: Json) => ((data.messages ?? []) as Json[]).map((m) => ({ messageId: m.messageId, timestamp: String(m.timestamp ?? '').slice(0, 19), deliveries: m.deliveryCount ?? '', event: m.event ?? '', body: String(m.rawBody ?? '').slice(0, 80) })) + + noun.command('dead-letters ') + .description("A trigger's dead letters.") + .option('-l, --limit ', 'most messages', '20') + .option('--offset ', 'skip this many') + .action(async (trigger: string, options: { limit: string; offset?: string }) => { + const { c, data } = await run('getEsbDeadLettersByTrigger', { trigger }, { limit: options.limit, offset: options.offset }) + const rows = messageRows(data) + c.print({ data, rows, columns: ['messageId', 'timestamp', 'deliveries', 'event', 'body'], footer: `(${rows.length} dead letters${data.hasMore ? ', more with --offset' : ''})` }) + }) + + noun.command('messages ') + .description('Messages waiting on a destination (a topic needs --trigger: its messages are kept per trigger).') + .option('-t, --trigger ', 'the trigger (subscription) of a topic') + .option('-l, --limit ', 'most messages', '20') + .option('--offset ', 'skip this many') + .action(async (destination: string, options: { trigger?: string; limit: string; offset?: string }) => { + const { c, data } = await run('getEsbMessagesByDestination', { destination }, { trigger: options.trigger, limit: options.limit, offset: options.offset }) + const rows = messageRows(data) + c.print({ data, rows, columns: ['messageId', 'timestamp', 'deliveries', 'event', 'body'], footer: `(${rows.length} messages${data.hasMore ? ', more with --offset' : ''})` }) + }) +} + +export function registerExtensions(program: Command, ctx: () => Context): void { + program.command('extensions') + .description('Extensions (qbits) this client knows and which ones the server has installed.') + .action(async () => { + const c = ctx() + const registry = await c.extensions() + const rows: Json[] = KNOWN_EXTENSIONS.map((e) => { + const installed = registry.installed.find((i) => i.name === e.name) + return { + extension: e.name, + noun: `qqq ${nounOf(e.name)}`, + installed: installed ? installed.version ?? 'yes' : '', + status: !installed ? 'not installed' : installed.meetsMinimum ? 'ok' : `needs ${e.minVersion}+`, + client: e.documentVersion ?? '', + minimum: e.minVersion ?? '', + operations: operationsOf(e.name).length, + channels: e.channels.join(' '), + } + }) + for (const u of registry.unknown()) rows.push({ extension: u.name, noun: '', installed: u.version ?? 'yes', status: 'unknown to this client', client: '', minimum: '', operations: 0, channels: '' }) + c.print({ data: { installed: registry.installed, known: KNOWN_EXTENSIONS }, rows, columns: ['extension', 'noun', 'installed', 'status', 'client', 'minimum', 'operations', 'channels'], footer: `(installed: ${registry.describe()}; ${OPERATIONS.filter((o) => o.extension).length} extension operations in this client)` }) + }) + + for (const e of KNOWN_EXTENSIONS) { + const name = nounOf(e.name) + const noun = program.command(name).description(`${e.label} (${e.name} extension${e.minVersion ? ` ${e.minVersion}+` : ''}, ${e.repository}): ${e.description || 'operations'}`) + if (name !== e.name) noun.alias(e.name) + if (e.name === 'esb') registerEsb(noun, ctx) + if (e.name === 'collaboration') registerCollab(noun, ctx) + addOperationCommands(noun, e.name, e.pathPrefix, ctx) + noun.addHelpText('after', `\nEvery ${e.name} operation is a subcommand; path parameters go as arguments or --path name=value.\nNot installed on the server: exit 5 with the installed list (see \`qqq extensions\`).`) + } +} diff --git a/packages/cli/src/commands/variants.ts b/packages/cli/src/commands/variants.ts index f0c3f9d..d6a01a5 100644 --- a/packages/cli/src/commands/variants.ts +++ b/packages/cli/src/commands/variants.ts @@ -51,7 +51,7 @@ export async function chooseVariant(c: Context, meta: Json, typed: string | unde } else { throw new UsageError(`${meta.label} needs a ${label}: --variant ${variants.length ? ` (${variants.slice(0, 10).map((v) => `${v.name ?? v.id} (${v.id})`).join(', ')}${variants.length > 10 ? ', …' : ''})` : '; the server lists none'}`) } - // UI API 1.8.0 reads tableVariant on query, count, get, export and processes only (docs/server-findings.md #18) - if (options.write) c.note(`note: the server may ignore the ${label} on inserts, updates and deletes (UI API ${'1.8.0'}); see docs/server-findings.md #18`) + // UI API 1.8.0 reads tableVariant on query, count, get, export and processes only (docs/server-findings.md #19) + if (options.write) c.note(`note: the server may ignore the ${label} on inserts, updates and deletes (UI API ${'1.8.0'}); see docs/server-findings.md #19`) return chosen } diff --git a/packages/cli/src/context.ts b/packages/cli/src/context.ts index 1670fc8..8f84f77 100644 --- a/packages/cli/src/context.ts +++ b/packages/cli/src/context.ts @@ -10,8 +10,9 @@ import type { Command } from 'commander' import { UiApiError, unwrap, type UiApiClient } from '@qrun-io/qqq-ui-api-client' -import { FilterSyntaxError, OUTPUT_FORMATS, ProcessError, UnsafeFileNameError, defaultTimeZone, type DisplayOptions, applyQuery, callOperation, defaultFormat, getMetaData, getTableMetaData, render, type CallInput, type CallResult, type MetaDataDocument, type OutputFormat, type Printable } from '@qrun-io/qqq-core' -import { authenticatedFetch, clientFor, selectTarget, target, type Target } from './session.js' +import { Collaboration, ExtensionNotInstalledError, ExtensionRegistry, KNOWN_EXTENSIONS, FilterSyntaxError, OUTPUT_FORMATS, ProcessError, UnsafeFileNameError, defaultTimeZone, type DisplayOptions, applyQuery, callOperation, defaultFormat, extensionRegistry, getMetaData, getTableMetaData, render, type CallInput, type CallResult, type MetaDataDocument, type OutputFormat, type Printable } from '@qrun-io/qqq-core' +import { openRealtimeStream } from '@qrun-io/qqq-ui-api-client' +import { CLIENT_CHANNEL, authenticatedFetch, clientFor, currentToken, selectTarget, sessionCookieFor, target, type Target } from './session.js' /** Exit codes, as in the design doc (KofTwentyTwo ADR-0031 shape). */ export const EXIT = { ok: 0, error: 1, usage: 2, auth: 3, transient: 4, notFound: 5, validation: 6, unexpected: 70 } as const @@ -32,6 +33,7 @@ export interface GlobalOptions { export class Context { readonly options: GlobalOptions private clientCache?: UiApiClient + private registryCache?: Promise constructor(program: Command) { this.options = program.opts() @@ -94,6 +96,33 @@ export class Context { return getTableMetaData(this.server, table, authenticatedFetch(this.target), options) } + /** The server's extensions (GET /version, cached with the metadata). */ + extensions(options: { refresh?: boolean } = {}): Promise { + // QQQ_EXTENSION_CHECK=off treats every extension the client knows as installed, for mock + // servers (Prism) whose GET /version is only the document's example. + if (process.env.QQQ_EXTENSION_CHECK === 'off') return Promise.resolve(new ExtensionRegistry(KNOWN_EXTENSIONS.map((e) => ({ name: e.name, version: e.documentVersion, pathPrefix: e.pathPrefix, known: true, meetsMinimum: true })))) + this.registryCache ??= extensionRegistry(this.server, authenticatedFetch(this.target), options) + return this.registryCache + } + + /** The collaboration module for this server, with the realtime stream for presence. */ + async collaboration(): Promise { + const t = this.target + return new Collaboration(await this.extensions(), { + call: (id, input) => this.call(id, input), + openStream: (signal) => (async function* () { + const session = await sessionCookieFor(t) + yield* openRealtimeStream({ + baseUrl: t.server, + clientChannel: CLIENT_CHANNEL, + signal, + headers: session ? { Cookie: `sessionUUID=${session}` } : undefined, + token: session ? undefined : () => currentToken(t), + }) + })(), + }) + } + /** Calls an operation by id (the generic escape hatch). */ call(id: string, input: CallInput): Promise { return callOperation(this.server, id, input, authenticatedFetch(this.target)) @@ -130,6 +159,7 @@ export class UsageError extends Error {} /** Maps an error to its exit code and the stderr text. */ export function describeError(error: unknown, trace = false): { code: number; text: string } { if (error instanceof UsageError || error instanceof FilterSyntaxError || error instanceof UnsafeFileNameError) return { code: EXIT.usage, text: `Error: ${error.message}` } + if (error instanceof ExtensionNotInstalledError) return { code: EXIT.notFound, text: `Error: ${error.message}` } if (error instanceof UiApiError) { const lines = [`Error: ${error.message} (${error.code}, HTTP ${error.status}${error.traceId ? `, trace ${error.traceId}` : ''})`] for (const fieldError of error.fieldErrors) lines.push(` ${fieldError.field}: ${fieldError.message}`) diff --git a/packages/cli/src/main.ts b/packages/cli/src/main.ts index 094b3c8..aa75069 100644 --- a/packages/cli/src/main.ts +++ b/packages/cli/src/main.ts @@ -7,7 +7,8 @@ /** * qqq - the command-line client for QQQ applications. Every call is an operation of the QQQ UI API * (/qqq/v1); nothing is hard-coded about an application: apps, tables, fields and processes all - * come from metadata. Grammar: `qqq ` (table, process, job, widget, report, prefs, api), plus the flat + * come from metadata. Grammar: `qqq ` (table, process, job, widget, report, prefs, api, and one noun per + * extension: esb, collab, sql-workbench, ...), plus the flat * commands of 0.1 (apps, tables, query, get, run, jobs, tail) as aliases. */ @@ -20,6 +21,7 @@ import { registerAudit } from './commands/audit.js' import { registerAuth } from './commands/auth.js' import { registerCompletion } from './commands/completion.js' import { registerConfig } from './commands/config.js' +import { registerExtensions } from './commands/extensions.js' import { registerHelp } from './commands/help.js' import { registerJob } from './commands/job.js' import { registerMisc } from './commands/misc.js' @@ -59,6 +61,7 @@ registerSavedView(program, ctx) registerJob(program, ctx) registerWidget(program, ctx) registerApi(program, ctx) +registerExtensions(program, ctx) registerCompletion(program, ctx) registerConfig(program, ctx) registerHelp(program, ctx) diff --git a/packages/cli/src/test/extensions.test.ts b/packages/cli/src/test/extensions.test.ts new file mode 100644 index 0000000..b3536d8 --- /dev/null +++ b/packages/cli/src/test/extensions.test.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2026 QRun.IO, Inc. + * Licensed under the Apache License, Version 2.0 (see LICENSE). + */ + +import assert from 'node:assert/strict' +import { test } from 'node:test' +import { Command } from 'commander' +import { ExtensionNotInstalledError, ExtensionRegistry, KNOWN_EXTENSIONS, operationsOf } from '@qrun-io/qqq-core' +import { EXIT, describeError } from '../context.js' +import { nounOf, registerExtensions, subcommandNames } from '../commands/extensions.js' +import { presenceLine } from '../commands/collab.js' + +test('every operation of every extension is a uniquely named subcommand of its noun', () => { + const program = new Command() + registerExtensions(program, () => { throw new Error('not called') }) + for (const e of KNOWN_EXTENSIONS) { + const names = subcommandNames(e.name, e.pathPrefix, operationsOf(e.name)) + assert.equal(names.size, operationsOf(e.name).length, `${e.name}: one name per operation`) + const noun = program.commands.find((c) => c.name() === nounOf(e.name))! + assert.ok(noun, `noun for ${e.name}`) + for (const name of names.keys()) assert.ok(noun.commands.some((c) => c.name() === name), `${nounOf(e.name)} ${name}`) + } + const esb = subcommandNames('esb', '/esb', operationsOf('esb')) + assert.deepEqual([...esb.keys()].sort(), ['get-dead-letters', 'get-messages', 'get-overview', 'get-process', 'get-table']) + const collab = subcommandNames('collaboration', '/qbit/collaboration', operationsOf('collaboration')) + assert.equal(collab.get('get-records-comments')?.id, 'getQbitCollaborationRecordsByTableByPkComments') + assert.equal(collab.get('get-people-by-user-id')?.id, 'getQbitCollaborationPeopleByUserId') + const collabNoun = program.commands.find((c) => c.name() === 'collab')! + assert.deepEqual(collabNoun.aliases(), ['collaboration']) + for (const verb of ['presence', 'comments', 'favorites', 'recents', 'follow', 'unfollow', 'my-work', 'people']) assert.ok(collabNoun.commands.some((c) => c.name() === verb), verb) +}) + +test('a missing extension maps to exit 5 with the installed list', () => { + const error = new ExtensionNotInstalledError('collaboration', ExtensionRegistry.fromVersion({ extensions: [{ name: 'esb', version: '1.1.0' }] }).installed) + assert.deepEqual(describeError(error), { code: EXIT.notFound, text: 'Error: extension collaboration is not installed on this server (installed: esb 1.1.0)' }) +}) + +test('presence lines say who is there and since when', () => { + const since = new Date(2026, 9, 31, 17, 50, 1) + assert.equal(presenceLine({ available: true, scope: { table: 'person', pk: '1' }, count: 0, people: [], live: true }), 'nobody on person 1') + assert.equal(presenceLine({ available: true, scope: { table: 'person' }, count: 2, people: [{ userId: 'a', name: 'Alice', mode: 'VIEWING', since }, { userId: 'b', name: 'Bob', mode: 'EDITING', fieldName: 'email', since }], live: true }), '2 on person: Alice (viewing since 17:50:01), Bob (editing email since 17:50:01)') + assert.match(presenceLine({ available: false, scope: { table: 'person' }, count: 0, people: [], live: false }), /not installed/) +}) diff --git a/packages/core/README.md b/packages/core/README.md index b78790d..3442885 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -19,6 +19,8 @@ what it produces; the TUI draws it. | `records/record-view` | the record view as text: sections without hidden sections or fields, adornments (LINK, CHIP, REVEAL, RENDER_HTML, CODE_EDITOR, ERROR, FILE_DOWNLOAD, WIDGET, TOOLTIP), view-screen help by role | | `widgets/render-model` | any widget payload to neutral blocks (heading, stat, table, series, pairs, steps, alert, link, rule, children) and blocks to text | | `metadata/cache` | on-disk cache of `GET /metaData` and table definitions per server, with a TTL and offline reads | +| `extensions/registry` | every extension the client document carries (operations, documented minimum version, realtime channels), joined with the server's `GET /version`: `has`, `require` (typed `ExtensionNotInstalledError`), unknown extensions kept; see `src/extensions/README.md` | +| `extensions/collaboration` | the collaboration qbit: live presence (`joinPresence`, a no-op without the extension), comments, favorites, recents, follow, people, my work | | `session/profiles`, `session/keyring` | named profiles and an OS keyring without native modules (Keychain, Secret Service, DPAPI, file) | Rules the kernel keeps for both heads: every call is a spec operation named by `operationId`; text comes from the diff --git a/packages/core/src/api/operations.ts b/packages/core/src/api/operations.ts index 088f6f9..8edaa72 100644 --- a/packages/core/src/api/operations.ts +++ b/packages/core/src/api/operations.ts @@ -3,7 +3,7 @@ * Licensed under the Apache License, Version 2.0 (see LICENSE). */ -// Generated by scripts/gen-operations.mjs from the UI API 1.8.0 document. Do not edit. +// Generated by scripts/gen-operations.mjs from the UI API 1.8.0 document (core and 13 extensions). Do not edit. export interface OperationInfo { id: string @@ -14,31 +14,85 @@ export interface OperationInfo { pathParams: string[] queryParams: string[] bodyTypes: string[] + /** The extension (qbit or module) that serves this operation; absent for core operations. */ + extension?: string +} + +/** An extension document merged into the client document (info.x-qqq-extensions). */ +export interface DocumentExtension { + name: string + version: string + pathPrefix?: string + description?: string } export const UI_API_DOCUMENT_VERSION = "1.8.0" +/** The extensions merged into the client document, with the versions it was generated from. */ +export const DOCUMENT_EXTENSIONS: DocumentExtension[] = [ + {"name":"esb","version":"1.1.0","pathPrefix":"/esb","description":"ESB overview, the ESB of tables and processes, and messages and dead letters on destinations."}, + {"name":"health","version":"1.1.0","pathPrefix":"/health","description":"Central health summary, components, history and on-demand checks."}, + {"name":"alerts","version":"1.2.0","pathPrefix":"/alerts","description":"Alerts inbox and record panel"}, + {"name":"assistant","version":"1.6.0","pathPrefix":"/assistant","description":"QQQ Assistant: conversations, streamed turns, feedback, pending actions and data access explanations"}, + {"name":"collaboration","version":"1.1.0","pathPrefix":"/qbit/collaboration","description":"Record collaboration: favorites, recents, attachments, tags, conversations, following, timeline, people and presence"}, + {"name":"data-analysis","version":"1.5.0","pathPrefix":"/qbit/data-analysis","description":"Profiles, pivots, comparisons, distribution shifts, correlations, scatter samples, crosstabs and anomaly watch previews as the signed-in user."}, + {"name":"db-performance","version":"1.0.0","pathPrefix":"/qbit/db-performance","description":"Database performance, live activity and audited query plans"}, + {"name":"edi","version":"1.1.0","pathPrefix":"/qbit/edi","description":"EDI sandbox and mapper, using the signed-in user's permissions."}, + {"name":"qa-capture","version":"1.0.0","pathPrefix":"/qbit/qa-capture","description":"QA bug capture: the user's capture capability and QA report creation"}, + {"name":"quick-search","version":"1.1.0","pathPrefix":"/qbit/quick-search","description":"Quick Search administration and suggestions"}, + {"name":"release-notes","version":"1.0.0","pathPrefix":"/qbit/release-notes","description":"What's new: published release notes and each user's unread count"}, + {"name":"secured-data","version":"1.1.0","pathPrefix":"/qbit/secured-data","description":"Reveal grants and break-glass status"}, + {"name":"sql-workbench","version":"1.1.0","pathPrefix":"/sql-workbench","description":"Audited SQL execution and notebooks"}, +] + export const OPERATIONS: OperationInfo[] = [ {"id":"addRelatedRecords","method":"POST","path":"/qqq/v1/table/{tableName}/relatedRecordPicker/{pickerName}/add","summary":"Add child or join rows for picked records (MULTI_CHILD, LINK)","tag":"Tables","pathParams":["tableName","pickerName"],"queryParams":[],"bodyTypes":["application/json"]}, + {"id":"alertsInbox","method":"GET","path":"/qqq/v1/alerts/inbox","summary":"Page the notification inbox","tag":"alerts","pathParams":[],"queryParams":["status","category","severity","offset","limit"],"bodyTypes":[],"extension":"alerts"}, + {"id":"alertsInboxDismiss","method":"POST","path":"/qqq/v1/alerts/inbox/dismiss","summary":"Dismiss own notifications","tag":"alerts","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"alerts"}, + {"id":"alertsInboxRead","method":"POST","path":"/qqq/v1/alerts/inbox/read","summary":"Mark own notifications read","tag":"alerts","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"alerts"}, + {"id":"alertsInboxSummary","method":"GET","path":"/qqq/v1/alerts/inbox/summary","summary":"Read the bell summary","tag":"alerts","pathParams":[],"queryParams":[],"bodyTypes":[],"extension":"alerts"}, + {"id":"alertsInboxUnread","method":"POST","path":"/qqq/v1/alerts/inbox/unread","summary":"Mark own notifications unread","tag":"alerts","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"alerts"}, + {"id":"alertsRecordPanel","method":"GET","path":"/qqq/v1/alerts/record-panel","summary":"Read visible alerts for a record","tag":"alerts","pathParams":[],"queryParams":["tableName","recordId"],"bodyTypes":[],"extension":"alerts"}, {"id":"cancelJob","method":"POST","path":"/qqq/v1/jobs/{jobId}/cancel","summary":"Jobs: cancel","tag":"Processes","pathParams":["jobId"],"queryParams":[],"bodyTypes":[]}, {"id":"cancelProcess","method":"POST","path":"/qqq/v1/processes/{processName}/{processUUID}/cancel","summary":"Cancel a running process","tag":"Processes","pathParams":["processName","processUUID"],"queryParams":["tableVariant"],"bodyTypes":[]}, {"id":"chooseDeliveryTargets","method":"POST","path":"/qqq/v1/delivery/destinations/{name}/targets","summary":"Describe the next delivery target","tag":"General","pathParams":["name"],"queryParams":[],"bodyTypes":["application/json"]}, {"id":"countTable","method":"POST","path":"/qqq/v1/table/{tableName}/count","summary":"Count records in a table","tag":"Tables","pathParams":["tableName"],"queryParams":["includeDistinct"],"bodyTypes":["application/json"]}, + {"id":"dbPerformanceActivity","method":"GET","path":"/qqq/v1/qbit/db-performance/activity","summary":"Database Performance activity","tag":"","pathParams":[],"queryParams":["backend"],"bodyTypes":[],"extension":"db-performance"}, + {"id":"dbPerformanceExplain","method":"POST","path":"/qqq/v1/qbit/db-performance/explain","summary":"Explain a PostgreSQL query","tag":"","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"db-performance"}, + {"id":"dbPerformanceLookup","method":"GET","path":"/qqq/v1/qbit/db-performance/statements/lookup","summary":"Database Performance lookup","tag":"","pathParams":[],"queryParams":["backend","sql"],"bodyTypes":[],"extension":"db-performance"}, + {"id":"dbPerformanceOverview","method":"GET","path":"/qqq/v1/qbit/db-performance/overview","summary":"Database Performance overview","tag":"","pathParams":[],"queryParams":["backend"],"bodyTypes":[],"extension":"db-performance"}, + {"id":"deleteAssistantConversationsById","method":"DELETE","path":"/qqq/v1/assistant/conversations/{id}","summary":"Delete a conversation","tag":"assistant","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"assistant"}, + {"id":"deleteQbitCollaborationAttachmentsById","method":"DELETE","path":"/qqq/v1/qbit/collaboration/attachments/{id}","summary":"Delete an attachment","tag":"collaboration","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"collaboration"}, + {"id":"deleteQbitCollaborationCommentsById","method":"DELETE","path":"/qqq/v1/qbit/collaboration/comments/{id}","summary":"Delete a comment thread","tag":"collaboration","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"collaboration"}, + {"id":"deleteQbitCollaborationFavorites","method":"DELETE","path":"/qqq/v1/qbit/collaboration/favorites","summary":"Unstar a target","tag":"collaboration","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"deleteQbitCollaborationPresence","method":"DELETE","path":"/qqq/v1/qbit/collaboration/presence","summary":"Leave presence","tag":"collaboration","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"deleteQbitCollaborationRecordsByTableByPkFollow","method":"DELETE","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/follow","summary":"Unfollow a record","tag":"collaboration","pathParams":["table","pk"],"queryParams":[],"bodyTypes":[],"extension":"collaboration"}, + {"id":"deleteQbitDataAnalysisSavedByIdStar","method":"DELETE","path":"/qqq/v1/qbit/data-analysis/saved/{id}/star","summary":"Unstar a saved analysis","tag":"data-analysis","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"data-analysis"}, {"id":"deleteRecord","method":"DELETE","path":"/qqq/v1/table/{tableName}/{primaryKey}","summary":"Delete a record from a table","tag":"Tables","pathParams":["tableName","primaryKey"],"queryParams":[],"bodyTypes":[]}, {"id":"download","method":"GET","path":"/qqq/v1/download/{file}","summary":"Download a file","tag":"General","pathParams":["file"],"queryParams":["filePath","storageTableName","storageReference"],"bodyTypes":[]}, {"id":"downloadRecordFieldFile","method":"GET","path":"/qqq/v1/table/{tableName}/{primaryKey}/{fieldName}/{filename}","summary":"Download a field value from a record","tag":"Tables","pathParams":["tableName","primaryKey","fieldName","filename"],"queryParams":[],"bodyTypes":[]}, {"id":"exportTable","method":"POST","path":"/qqq/v1/table/{tableName}/export","summary":"Export records from a table","tag":"Tables","pathParams":["tableName"],"queryParams":[],"bodyTypes":["application/json"]}, + {"id":"getAssistantAccess","method":"GET","path":"/qqq/v1/assistant/access","summary":"Explain access: which UI API operations the assistant could call for this user, and why not","tag":"assistant","pathParams":[],"queryParams":["table","prompt","turnId"],"bodyTypes":[],"extension":"assistant"}, + {"id":"getAssistantActionsById","method":"GET","path":"/qqq/v1/assistant/actions/{id}","summary":"A write the assistant proposed, and its state","tag":"assistant","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"assistant"}, + {"id":"getAssistantConfig","method":"GET","path":"/qqq/v1/assistant/config","summary":"Whether the assistant is available to this user, its persona and limits","tag":"assistant","pathParams":[],"queryParams":[],"bodyTypes":[],"extension":"assistant"}, + {"id":"getAssistantConversations","method":"GET","path":"/qqq/v1/assistant/conversations","summary":"The user's own conversations","tag":"assistant","pathParams":[],"queryParams":["status"],"bodyTypes":[],"extension":"assistant"}, + {"id":"getAssistantConversationsById","method":"GET","path":"/qqq/v1/assistant/conversations/{id}","summary":"A conversation and a page of its messages","tag":"assistant","pathParams":["id"],"queryParams":["before","limit"],"bodyTypes":[],"extension":"assistant"}, + {"id":"getAssistantTurnsActive","method":"GET","path":"/qqq/v1/assistant/turns/active","summary":"Find the user's active assistant runs","tag":"assistant","pathParams":[],"queryParams":[],"bodyTypes":[],"extension":"assistant"}, + {"id":"getAssistantTurnsByTurnIdEvents","method":"GET","path":"/qqq/v1/assistant/turns/{turnId}/events","summary":"Resume a turn's events after a sequence number (replay, then the live tail)","tag":"assistant","pathParams":["turnId"],"queryParams":["after"],"bodyTypes":[],"extension":"assistant"}, {"id":"getAssociatedScriptLogs","method":"GET","path":"/qqq/v1/table/{tableName}/{primaryKey}/developer/associatedScript/{fieldName}/{scriptRevisionId}/logs","summary":"Get the logs of a record's associated script revision (developer mode)","tag":"Tables","pathParams":["tableName","primaryKey","fieldName","scriptRevisionId"],"queryParams":[],"bodyTypes":[]}, {"id":"getAuthenticationMetaData","method":"GET","path":"/qqq/v1/metaData/authentication","summary":"Get authentication metaData","tag":"Authentication","pathParams":[],"queryParams":[],"bodyTypes":[]}, {"id":"getAvatar","method":"GET","path":"/qqq/v1/avatars/{avatarId}","summary":"Get an avatar","tag":"Authentication","pathParams":["avatarId"],"queryParams":["size","v"],"bodyTypes":[]}, {"id":"getBrandingAsset","method":"GET","path":"/qqq/v1/branding/{role}","summary":"Get a branding image","tag":"Authentication","pathParams":["role"],"queryParams":[],"bodyTypes":[]}, {"id":"getBulkLoadUploadProfile","method":"GET","path":"/qqq/v1/bulkLoad/uploads/{uploadRef}/profile","summary":"Profile an uploaded file for a bulk load","tag":"Bulk Load","pathParams":["uploadRef"],"queryParams":["tableName","sampleCount"],"bodyTypes":[]}, {"id":"getDeliveryOutput","method":"GET","path":"/qqq/v1/delivery/output/{logId}","summary":"Download stored output as its owner or delivery administrator","tag":"General","pathParams":["logId"],"queryParams":[],"bodyTypes":[]}, - {"id":"getEsbDeadLettersByTrigger","method":"GET","path":"/qqq/v1/esb/deadLetters/{trigger}","summary":"Dead letters of a trigger","tag":"ESB","pathParams":["trigger"],"queryParams":["offset","limit"],"bodyTypes":[]}, - {"id":"getEsbMessagesByDestination","method":"GET","path":"/qqq/v1/esb/messages/{destination}","summary":"Messages on a destination","tag":"ESB","pathParams":["destination"],"queryParams":["trigger","offset","limit"],"bodyTypes":[]}, - {"id":"getEsbOverview","method":"GET","path":"/qqq/v1/esb/overview","summary":"ESB overview","tag":"ESB","pathParams":[],"queryParams":[],"bodyTypes":[]}, - {"id":"getEsbProcessByProcess","method":"GET","path":"/qqq/v1/esb/process/{process}","summary":"ESB of a process","tag":"ESB","pathParams":["process"],"queryParams":[],"bodyTypes":[]}, - {"id":"getEsbTableByTable","method":"GET","path":"/qqq/v1/esb/table/{table}","summary":"ESB of a table","tag":"ESB","pathParams":["table"],"queryParams":[],"bodyTypes":[]}, + {"id":"getEsbDeadLettersByTrigger","method":"GET","path":"/qqq/v1/esb/deadLetters/{trigger}","summary":"Dead letters of a trigger","tag":"ESB","pathParams":["trigger"],"queryParams":["offset","limit"],"bodyTypes":[],"extension":"esb"}, + {"id":"getEsbMessagesByDestination","method":"GET","path":"/qqq/v1/esb/messages/{destination}","summary":"Messages on a destination","tag":"ESB","pathParams":["destination"],"queryParams":["trigger","offset","limit"],"bodyTypes":[],"extension":"esb"}, + {"id":"getEsbOverview","method":"GET","path":"/qqq/v1/esb/overview","summary":"ESB overview","tag":"ESB","pathParams":[],"queryParams":[],"bodyTypes":[],"extension":"esb"}, + {"id":"getEsbProcessByProcess","method":"GET","path":"/qqq/v1/esb/process/{process}","summary":"ESB of a process","tag":"ESB","pathParams":["process"],"queryParams":[],"bodyTypes":[],"extension":"esb"}, + {"id":"getEsbTableByTable","method":"GET","path":"/qqq/v1/esb/table/{table}","summary":"ESB of a table","tag":"ESB","pathParams":["table"],"queryParams":[],"bodyTypes":[],"extension":"esb"}, + {"id":"getHealthChecksByNameHistory","method":"GET","path":"/qqq/v1/health/checks/{name}/history","summary":"Health history","tag":"Health","pathParams":["name"],"queryParams":["from","to","limit"],"bodyTypes":[],"extension":"health"}, + {"id":"getHealthComponentsByName","method":"GET","path":"/qqq/v1/health/components/{name}","summary":"Health component","tag":"Health","pathParams":["name"],"queryParams":[],"bodyTypes":[],"extension":"health"}, + {"id":"getHealthSummary","method":"GET","path":"/qqq/v1/health/summary","summary":"Health summary","tag":"Health","pathParams":[],"queryParams":[],"bodyTypes":[],"extension":"health"}, {"id":"getHelpCoverage","method":"GET","path":"/qqq/v1/help/coverage","summary":"Inspect application help coverage","tag":"General","pathParams":[],"queryParams":["kind","missingOnly","parentKey"],"bodyTypes":[]}, {"id":"getJob","method":"GET","path":"/qqq/v1/jobs/{jobId}","summary":"Jobs: detail","tag":"Processes","pathParams":["jobId"],"queryParams":[],"bodyTypes":[]}, {"id":"getJobProgress","method":"GET","path":"/qqq/v1/jobs/{jobId}/progress","summary":"Jobs: progress","tag":"Processes","pathParams":["jobId"],"queryParams":["afterLogId","logLimit"],"bodyTypes":[]}, @@ -47,6 +101,37 @@ export const OPERATIONS: OperationInfo[] = [ {"id":"getProcessMetaData","method":"GET","path":"/qqq/v1/metaData/process/{processName}","summary":"Get process metaData","tag":"Processes","pathParams":["processName"],"queryParams":[],"bodyTypes":[]}, {"id":"getProcessRecords","method":"GET","path":"/qqq/v1/processes/{processName}/{processUUID}/records","summary":"Get records from a process","tag":"Processes","pathParams":["processName","processUUID"],"queryParams":["skip","limit","tableVariant"],"bodyTypes":[]}, {"id":"getProcessStatus","method":"GET","path":"/qqq/v1/processes/{processName}/{processUUID}/status/{jobUUID}","summary":"Get job status","tag":"Processes","pathParams":["processName","processUUID","jobUUID"],"queryParams":["tableVariant"],"bodyTypes":[]}, + {"id":"getQbitCollaborationAccessRequestsMine","method":"GET","path":"/qqq/v1/qbit/collaboration/access-requests/mine","summary":"List my access requests","tag":"collaboration","pathParams":[],"queryParams":["limit","cursor"],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationAttachmentsByIdDownload","method":"GET","path":"/qqq/v1/qbit/collaboration/attachments/{id}/download","summary":"Get a temporary download URL; clients follow url","tag":"collaboration","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationAttachmentsByIdPreview","method":"GET","path":"/qqq/v1/qbit/collaboration/attachments/{id}/preview","summary":"Get a temporary preview URL; clients follow url","tag":"collaboration","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationCommentsByIdHistory","method":"GET","path":"/qqq/v1/qbit/collaboration/comments/{id}/history","summary":"Read comment edit history","tag":"collaboration","pathParams":["id"],"queryParams":["limit","cursor"],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationFavorites","method":"GET","path":"/qqq/v1/qbit/collaboration/favorites","summary":"List personal favorites","tag":"collaboration","pathParams":[],"queryParams":["limit","cursor"],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationMentionsCandidates","method":"GET","path":"/qqq/v1/qbit/collaboration/mentions/candidates","summary":"Find people to mention on a record","tag":"collaboration","pathParams":[],"queryParams":["table","pk","q","limit","cursor"],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationMyWork","method":"GET","path":"/qqq/v1/qbit/collaboration/my-work","summary":"Get my work summary","tag":"collaboration","pathParams":[],"queryParams":[],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationPeople","method":"GET","path":"/qqq/v1/qbit/collaboration/people","summary":"Search the active people directory","tag":"collaboration","pathParams":[],"queryParams":["q","limit"],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationPeopleByUserId","method":"GET","path":"/qqq/v1/qbit/collaboration/people/{userId}","summary":"Get an active directory person","tag":"collaboration","pathParams":["userId"],"queryParams":[],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationPresence","method":"GET","path":"/qqq/v1/qbit/collaboration/presence","summary":"Get presence snapshot","tag":"collaboration","pathParams":[],"queryParams":["table","pk"],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationRecents","method":"GET","path":"/qqq/v1/qbit/collaboration/recents","summary":"List recent targets","tag":"collaboration","pathParams":[],"queryParams":["limit","cursor"],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationRecordsByTableByPkAttachments","method":"GET","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/attachments","summary":"List record attachments","tag":"collaboration","pathParams":["table","pk"],"queryParams":["limit","cursor"],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationRecordsByTableByPkComments","method":"GET","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/comments","summary":"Page record comment threads","tag":"collaboration","pathParams":["table","pk"],"queryParams":["limit","cursor"],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationRecordsByTableByPkFollow","method":"GET","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/follow","summary":"Get the caller's follow state","tag":"collaboration","pathParams":["table","pk"],"queryParams":[],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationRecordsByTableByPkFollowers","method":"GET","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/followers","summary":"List record followers","tag":"collaboration","pathParams":["table","pk"],"queryParams":["limit","cursor"],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationRecordsByTableByPkLink","method":"GET","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/link","summary":"Get a record link","tag":"collaboration","pathParams":["table","pk"],"queryParams":[],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationRecordsByTableByPkTags","method":"GET","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/tags","summary":"List applied record tags","tag":"collaboration","pathParams":["table","pk"],"queryParams":["limit","cursor"],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationRecordsByTableByPkTasks","method":"GET","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/tasks","summary":"List record tasks","tag":"collaboration","pathParams":["table","pk"],"queryParams":["includeDone","limit","cursor"],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationRecordsByTableByPkTimeline","method":"GET","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/timeline","summary":"Page the merged record timeline","tag":"collaboration","pathParams":["table","pk"],"queryParams":["before","types","limit","cursor"],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationTags","method":"GET","path":"/qqq/v1/qbit/collaboration/tags","summary":"Search table tag vocabulary","tag":"collaboration","pathParams":[],"queryParams":["table","q","limit"],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitCollaborationTasksMine","method":"GET","path":"/qqq/v1/qbit/collaboration/tasks/mine","summary":"List my tasks","tag":"collaboration","pathParams":[],"queryParams":["status","limit","cursor"],"bodyTypes":[],"extension":"collaboration"}, + {"id":"getQbitDataAnalysisRunsByRunId","method":"GET","path":"/qqq/v1/qbit/data-analysis/runs/{runId}","summary":"Get an exact profile run","tag":"data-analysis","pathParams":["runId"],"queryParams":[],"bodyTypes":[],"extension":"data-analysis"}, + {"id":"getQbitDataAnalysisSaved","method":"GET","path":"/qqq/v1/qbit/data-analysis/saved","summary":"List visible saved analyses","tag":"data-analysis","pathParams":[],"queryParams":[],"bodyTypes":[],"extension":"data-analysis"}, + {"id":"getQbitDataAnalysisSavedByIdExport","method":"GET","path":"/qqq/v1/qbit/data-analysis/saved/{id}/export","summary":"Export a saved analysis","tag":"data-analysis","pathParams":["id"],"queryParams":["format"],"bodyTypes":[],"extension":"data-analysis"}, + {"id":"getQbitDataAnalysisTablesByTableCapabilities","method":"GET","path":"/qqq/v1/qbit/data-analysis/tables/{table}/capabilities","summary":"Check analysis availability","tag":"data-analysis","pathParams":["table"],"queryParams":[],"bodyTypes":[],"extension":"data-analysis"}, + {"id":"getQbitEdiGuidesByGuideIdTree","method":"GET","path":"/qqq/v1/qbit/edi/guides/{guideId}/tree","summary":"Read the guide tree","tag":"edi","pathParams":["guideId"],"queryParams":[],"bodyTypes":[],"extension":"edi"}, + {"id":"getQbitEdiMapsByMapIdTarget","method":"GET","path":"/qqq/v1/qbit/edi/maps/{mapId}/target","summary":"Read target metadata and map rules","tag":"edi","pathParams":["mapId"],"queryParams":[],"bodyTypes":[],"extension":"edi"}, + {"id":"getQbitSecuredDataRevealOptions","method":"GET","path":"/qqq/v1/qbit/secured-data/reveal/options","summary":"RevealOptions","tag":"secured-data","pathParams":[],"queryParams":["tableName","fieldName"],"bodyTypes":[],"extension":"secured-data"}, + {"id":"getQbitSecuredDataStatus","method":"GET","path":"/qqq/v1/qbit/secured-data/status","summary":"Status","tag":"secured-data","pathParams":[],"queryParams":[],"bodyTypes":[],"extension":"secured-data"}, + {"id":"getQuickSearchStatus","method":"GET","path":"/qqq/v1/qbit/quick-search/status","summary":"Get Quick Search status","tag":"quick-search","pathParams":[],"queryParams":[],"bodyTypes":[],"extension":"quick-search"}, + {"id":"getQuickSearchSuggestions","method":"GET","path":"/qqq/v1/qbit/quick-search/suggest","summary":"Get Quick Search suggestions","tag":"quick-search","pathParams":[],"queryParams":["q","limitPerTable","maxTables","tables"],"bodyTypes":[],"extension":"quick-search"}, {"id":"getRecord","method":"GET","path":"/qqq/v1/table/{tableName}/{primaryKey}","summary":"Get a record from a table by primary key","tag":"Tables","pathParams":["tableName","primaryKey"],"queryParams":["includeAssociations","queryJoins","tableVariant"],"bodyTypes":[]}, {"id":"getRecordDeveloperMode","method":"GET","path":"/qqq/v1/table/{tableName}/{primaryKey}/developer","summary":"Get a record's associated scripts (developer mode)","tag":"Tables","pathParams":["tableName","primaryKey"],"queryParams":[],"bodyTypes":[]}, {"id":"getRecordFeatures","method":"GET","path":"/qqq/v1/table/{tableName}/{primaryKey}/features","summary":"Get record collaboration features","tag":"Tables","pathParams":["tableName","primaryKey"],"queryParams":[],"bodyTypes":[]}, @@ -68,9 +153,61 @@ export const OPERATIONS: OperationInfo[] = [ {"id":"manageSession","method":"POST","path":"/qqq/v1/manageSession","summary":"Create a session","tag":"Authentication","pathParams":[],"queryParams":[],"bodyTypes":["application/json"]}, {"id":"oidcBackChannelLogout","method":"POST","path":"/qqq/v1/oidc/backchannel-logout","summary":"OIDC Back-Channel Logout","tag":"Authentication","pathParams":[],"queryParams":[],"bodyTypes":[]}, {"id":"openRealtimeStream","method":"GET","path":"/qqq/v1/realtime/stream","summary":"Open the realtime event stream","tag":"General","pathParams":[],"queryParams":[],"bodyTypes":[]}, + {"id":"patchAssistantConversationsById","method":"PATCH","path":"/qqq/v1/assistant/conversations/{id}","summary":"Rename, pin, archive or mark read a conversation","tag":"assistant","pathParams":["id"],"queryParams":[],"bodyTypes":["application/json"],"extension":"assistant"}, + {"id":"patchQbitCollaborationAttachmentsById","method":"PATCH","path":"/qqq/v1/qbit/collaboration/attachments/{id}","summary":"Rename or describe an attachment","tag":"collaboration","pathParams":["id"],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"patchQbitCollaborationCommentsById","method":"PATCH","path":"/qqq/v1/qbit/collaboration/comments/{id}","summary":"Edit the caller's comment","tag":"collaboration","pathParams":["id"],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"patchQbitCollaborationFavoritesOrder","method":"PATCH","path":"/qqq/v1/qbit/collaboration/favorites/order","summary":"Reorder personal favorites","tag":"collaboration","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"patchQbitCollaborationTasksById","method":"PATCH","path":"/qqq/v1/qbit/collaboration/tasks/{id}","summary":"Update a task","tag":"collaboration","pathParams":["id"],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"postAssistantActionsByIdConfirm","method":"POST","path":"/qqq/v1/assistant/actions/{id}/confirm","summary":"Confirm a proposed write: it runs once, through the UI API, with this request's session","tag":"assistant","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"assistant"}, + {"id":"postAssistantActionsByIdReject","method":"POST","path":"/qqq/v1/assistant/actions/{id}/reject","summary":"Cancel a proposed write; nothing changes","tag":"assistant","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"assistant"}, + {"id":"postAssistantClientErrors","method":"POST","path":"/qqq/v1/assistant/client-errors","summary":"Report an error the client hit while showing the assistant (stored for administrators, rate limited per user)","tag":"assistant","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"assistant"}, + {"id":"postAssistantConversations","method":"POST","path":"/qqq/v1/assistant/conversations","summary":"Start a conversation","tag":"assistant","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"assistant"}, + {"id":"postAssistantConversationsByIdTurns","method":"POST","path":"/qqq/v1/assistant/conversations/{id}/turns","summary":"Ask: start a turn and stream the reply as server-sent events","tag":"assistant","pathParams":["id"],"queryParams":[],"bodyTypes":["application/json"],"extension":"assistant"}, + {"id":"postAssistantMessagesByIdFeedback","method":"POST","path":"/qqq/v1/assistant/messages/{id}/feedback","summary":"Thumbs up or down on an assistant message","tag":"assistant","pathParams":["id"],"queryParams":[],"bodyTypes":["application/json"],"extension":"assistant"}, + {"id":"postAssistantTurnsByTurnIdCancel","method":"POST","path":"/qqq/v1/assistant/turns/{turnId}/cancel","summary":"Stop a running turn","tag":"assistant","pathParams":["turnId"],"queryParams":[],"bodyTypes":[],"extension":"assistant"}, + {"id":"postHealthChecksByNameRun","method":"POST","path":"/qqq/v1/health/checks/{name}/run","summary":"Health run","tag":"Health","pathParams":["name"],"queryParams":[],"bodyTypes":[],"extension":"health"}, + {"id":"postQbitCollaborationAccessRequests","method":"POST","path":"/qqq/v1/qbit/collaboration/access-requests","summary":"Request access to a record","tag":"collaboration","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"postQbitCollaborationCommentsByIdReopen","method":"POST","path":"/qqq/v1/qbit/collaboration/comments/{id}/reopen","summary":"Reopen a comment thread","tag":"collaboration","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"collaboration"}, + {"id":"postQbitCollaborationCommentsByIdResolve","method":"POST","path":"/qqq/v1/qbit/collaboration/comments/{id}/resolve","summary":"Resolve a comment thread","tag":"collaboration","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"collaboration"}, + {"id":"postQbitCollaborationPresence","method":"POST","path":"/qqq/v1/qbit/collaboration/presence","summary":"Renew presence","tag":"collaboration","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"postQbitCollaborationRecents","method":"POST","path":"/qqq/v1/qbit/collaboration/recents","summary":"Record a recent view","tag":"collaboration","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"postQbitCollaborationRecordsByTableByPkAttachments","method":"POST","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/attachments","summary":"Upload an attachment","tag":"collaboration","pathParams":["table","pk"],"queryParams":[],"bodyTypes":["multipart/form-data"],"extension":"collaboration"}, + {"id":"postQbitCollaborationRecordsByTableByPkComments","method":"POST","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/comments","summary":"Post a comment or reply","tag":"collaboration","pathParams":["table","pk"],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"postQbitCollaborationRecordsByTableByPkShares","method":"POST","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/shares","summary":"Share a record","tag":"collaboration","pathParams":["table","pk"],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"postQbitCollaborationRecordsByTableByPkSharesPreview","method":"POST","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/shares/preview","summary":"Preview share recipients","tag":"collaboration","pathParams":["table","pk"],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"postQbitCollaborationRecordsByTableByPkTasks","method":"POST","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/tasks","summary":"Create a task","tag":"collaboration","pathParams":["table","pk"],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"postQbitCollaborationTags","method":"POST","path":"/qqq/v1/qbit/collaboration/tags","summary":"Create or suggest a tag","tag":"collaboration","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"postQbitDataAnalysisExport","method":"POST","path":"/qqq/v1/qbit/data-analysis/export","summary":"Export an analysis result","tag":"data-analysis","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"data-analysis"}, + {"id":"postQbitDataAnalysisRuns","method":"POST","path":"/qqq/v1/qbit/data-analysis/runs","summary":"Start an exact profile run","tag":"data-analysis","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"data-analysis"}, + {"id":"postQbitDataAnalysisSavedByIdRun","method":"POST","path":"/qqq/v1/qbit/data-analysis/saved/{id}/run","summary":"Run a saved analysis","tag":"data-analysis","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"data-analysis"}, + {"id":"postQbitDataAnalysisTablesByTableColumnProfile","method":"POST","path":"/qqq/v1/qbit/data-analysis/tables/{table}/column-profile","summary":"Profile one column","tag":"data-analysis","pathParams":["table"],"queryParams":[],"bodyTypes":["application/json"],"extension":"data-analysis"}, + {"id":"postQbitDataAnalysisTablesByTableCompare","method":"POST","path":"/qqq/v1/qbit/data-analysis/tables/{table}/compare","summary":"Compare two populations","tag":"data-analysis","pathParams":["table"],"queryParams":[],"bodyTypes":["application/json"],"extension":"data-analysis"}, + {"id":"postQbitDataAnalysisTablesByTableCorrelation","method":"POST","path":"/qqq/v1/qbit/data-analysis/tables/{table}/correlation","summary":"Find numeric relationships","tag":"data-analysis","pathParams":["table"],"queryParams":[],"bodyTypes":["application/json"],"extension":"data-analysis"}, + {"id":"postQbitDataAnalysisTablesByTableCrosstab","method":"POST","path":"/qqq/v1/qbit/data-analysis/tables/{table}/crosstab","summary":"Cross-tabulate two fields","tag":"data-analysis","pathParams":["table"],"queryParams":[],"bodyTypes":["application/json"],"extension":"data-analysis"}, + {"id":"postQbitDataAnalysisTablesByTableDistinctValues","method":"POST","path":"/qqq/v1/qbit/data-analysis/tables/{table}/distinct-values","summary":"List distinct column values","tag":"data-analysis","pathParams":["table"],"queryParams":[],"bodyTypes":["application/json"],"extension":"data-analysis"}, + {"id":"postQbitDataAnalysisTablesByTableDuplicates","method":"POST","path":"/qqq/v1/qbit/data-analysis/tables/{table}/duplicates","summary":"Find duplicate groups","tag":"data-analysis","pathParams":["table"],"queryParams":[],"bodyTypes":["application/json"],"extension":"data-analysis"}, + {"id":"postQbitDataAnalysisTablesByTablePivot","method":"POST","path":"/qqq/v1/qbit/data-analysis/tables/{table}/pivot","summary":"Explore a pivot table","tag":"data-analysis","pathParams":["table"],"queryParams":[],"bodyTypes":["application/json"],"extension":"data-analysis"}, + {"id":"postQbitDataAnalysisTablesByTableScatter","method":"POST","path":"/qqq/v1/qbit/data-analysis/tables/{table}/scatter","summary":"Inspect a numeric relationship","tag":"data-analysis","pathParams":["table"],"queryParams":[],"bodyTypes":["application/json"],"extension":"data-analysis"}, + {"id":"postQbitDataAnalysisTablesByTableShift","method":"POST","path":"/qqq/v1/qbit/data-analysis/tables/{table}/shift","summary":"Measure distribution shift over time","tag":"data-analysis","pathParams":["table"],"queryParams":[],"bodyTypes":["application/json"],"extension":"data-analysis"}, + {"id":"postQbitDataAnalysisTablesByTableSql","method":"POST","path":"/qqq/v1/qbit/data-analysis/tables/{table}/sql","summary":"Read an analysis aggregate SQL statement","tag":"data-analysis","pathParams":["table"],"queryParams":[],"bodyTypes":["application/json"],"extension":"data-analysis"}, + {"id":"postQbitDataAnalysisTablesByTableTableProfile","method":"POST","path":"/qqq/v1/qbit/data-analysis/tables/{table}/table-profile","summary":"Profile table completeness and keys","tag":"data-analysis","pathParams":["table"],"queryParams":[],"bodyTypes":["application/json"],"extension":"data-analysis"}, + {"id":"postQbitDataAnalysisWatchesByIdPreview","method":"POST","path":"/qqq/v1/qbit/data-analysis/watches/{id}/preview","summary":"Preview an anomaly watch","tag":"data-analysis","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"data-analysis"}, + {"id":"postQbitEdiMapsByMapIdValidate","method":"POST","path":"/qqq/v1/qbit/edi/maps/{mapId}/validate","summary":"Validate unsaved map rules","tag":"edi","pathParams":["mapId"],"queryParams":[],"bodyTypes":["application/json"],"extension":"edi"}, + {"id":"postQbitEdiSandboxPreview","method":"POST","path":"/qqq/v1/qbit/edi/sandbox/preview","summary":"Preview an encrypted sample with optional unsaved rules","tag":"edi","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"edi"}, + {"id":"postQbitSecuredDataReveal","method":"POST","path":"/qqq/v1/qbit/secured-data/reveal","summary":"Reveal","tag":"secured-data","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"secured-data"}, {"id":"prepareRelatedRecordPicker","method":"POST","path":"/qqq/v1/table/{tableName}/relatedRecordPicker/{pickerName}/prepare","summary":"Prepare child rows for picked records (MULTI_CHILD, LINK)","tag":"Tables","pathParams":["tableName","pickerName"],"queryParams":[],"bodyTypes":["application/json"]}, + {"id":"putQbitCollaborationFavorites","method":"PUT","path":"/qqq/v1/qbit/collaboration/favorites","summary":"Star a target","tag":"collaboration","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"putQbitCollaborationRecordsByTableByPkAssignment","method":"PUT","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/assignment","summary":"Set record owner and assignee","tag":"collaboration","pathParams":["table","pk"],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"putQbitCollaborationRecordsByTableByPkFollow","method":"PUT","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/follow","summary":"Follow a record and configure notifications","tag":"collaboration","pathParams":["table","pk"],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"putQbitCollaborationRecordsByTableByPkTags","method":"PUT","path":"/qqq/v1/qbit/collaboration/records/{table}/{pk}/tags","summary":"Add and remove record tags","tag":"collaboration","pathParams":["table","pk"],"queryParams":[],"bodyTypes":["application/json"],"extension":"collaboration"}, + {"id":"putQbitDataAnalysisSavedByIdStar","method":"PUT","path":"/qqq/v1/qbit/data-analysis/saved/{id}/star","summary":"Star a saved analysis","tag":"data-analysis","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"data-analysis"}, + {"id":"qaCaptureCapability","method":"GET","path":"/qqq/v1/qbit/qa-capture/capability","summary":"Read the QA capture capability","tag":"","pathParams":[],"queryParams":[],"bodyTypes":[],"extension":"qa-capture"}, + {"id":"qaCaptureReportCreate","method":"POST","path":"/qqq/v1/qbit/qa-capture/report","summary":"Create a QA report","tag":"","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"qa-capture"}, {"id":"queryRelatedRecordPicker","method":"POST","path":"/qqq/v1/table/{tableName}/relatedRecordPicker/{pickerName}/query","summary":"Query the records a related-record picker offers","tag":"Tables","pathParams":["tableName","pickerName"],"queryParams":[],"bodyTypes":["application/json"]}, {"id":"queryTable","method":"POST","path":"/qqq/v1/table/{tableName}/query","summary":"Query for records from a table","tag":"Tables","pathParams":["tableName"],"queryParams":[],"bodyTypes":["application/json"]}, + {"id":"releaseNotesReleases","method":"GET","path":"/qqq/v1/qbit/release-notes/releases","summary":"Published release notes","tag":"release-notes","pathParams":[],"queryParams":["limit","offset"],"bodyTypes":[],"extension":"release-notes"}, + {"id":"releaseNotesSeen","method":"POST","path":"/qqq/v1/qbit/release-notes/seen","summary":"Mark What's new as seen","tag":"release-notes","pathParams":[],"queryParams":[],"bodyTypes":[],"extension":"release-notes"}, + {"id":"releaseNotesSummary","method":"GET","path":"/qqq/v1/qbit/release-notes/summary","summary":"What's new summary","tag":"release-notes","pathParams":[],"queryParams":[],"bodyTypes":[],"extension":"release-notes"}, {"id":"removeRelatedRecords","method":"POST","path":"/qqq/v1/table/{tableName}/relatedRecordPicker/{pickerName}/remove","summary":"Unlink picked records (LINK)","tag":"Tables","pathParams":["tableName","pickerName"],"queryParams":[],"bodyTypes":["application/json"]}, {"id":"retryJob","method":"POST","path":"/qqq/v1/jobs/{jobId}/retry","summary":"Jobs: retry","tag":"Processes","pathParams":["jobId"],"queryParams":[],"bodyTypes":[]}, {"id":"runFormAdjuster","method":"POST","path":"/qqq/v1/table/{tableName}/formAdjuster/{identifier}/{event}","summary":"Run a form adjuster","tag":"Tables","pathParams":["tableName","identifier","event"],"queryParams":[],"bodyTypes":["application/json"]}, @@ -81,6 +218,27 @@ export const OPERATIONS: OperationInfo[] = [ {"id":"searchProcessPossibleValues","method":"POST","path":"/qqq/v1/processes/{processName}/possibleValues/{fieldName}","summary":"Search possible values for a process field","tag":"Processes","pathParams":["processName","fieldName"],"queryParams":[],"bodyTypes":["application/json"]}, {"id":"searchRecords","method":"POST","path":"/qqq/v1/search","summary":"Search records across tables","tag":"Tables","pathParams":[],"queryParams":[],"bodyTypes":["application/json"]}, {"id":"searchTablePossibleValues","method":"POST","path":"/qqq/v1/table/{tableName}/possibleValues/{fieldName}","summary":"Search possible values for a table field","tag":"Tables","pathParams":["tableName","fieldName"],"queryParams":[],"bodyTypes":["application/json"]}, + {"id":"sqlWorkbenchCancelExecution","method":"POST","path":"/qqq/v1/sql-workbench/executions/{uuid}/cancel","summary":"Cancel the caller's running execution","tag":"sql-workbench","pathParams":["uuid"],"queryParams":[],"bodyTypes":["application/json"],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchCreateNotebook","method":"POST","path":"/qqq/v1/sql-workbench/notebooks","summary":"Create a personal notebook","tag":"sql-workbench","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchCreateSnapshot","method":"POST","path":"/qqq/v1/sql-workbench/notebooks/{id}/snapshots","summary":"Pin the caller's cached result to an owned notebook","tag":"sql-workbench","pathParams":["id"],"queryParams":[],"bodyTypes":["application/json"],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchDeleteNotebook","method":"DELETE","path":"/qqq/v1/sql-workbench/notebooks/{id}","summary":"Delete an owned notebook","tag":"sql-workbench","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchDeleteSnapshot","method":"DELETE","path":"/qqq/v1/sql-workbench/notebooks/{id}/snapshots/{snapshotId}","summary":"Delete a snapshot from an owned notebook","tag":"sql-workbench","pathParams":["id","snapshotId"],"queryParams":[],"bodyTypes":[],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchDuplicateNotebook","method":"POST","path":"/qqq/v1/sql-workbench/notebooks/{id}/duplicate","summary":"Make a personal copy of a visible notebook","tag":"sql-workbench","pathParams":["id"],"queryParams":[],"bodyTypes":["application/json"],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchExecute","method":"POST","path":"/qqq/v1/sql-workbench/execute","summary":"Execute read-only SQL or preview and confirm a gated write","tag":"sql-workbench","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchExplain","method":"POST","path":"/qqq/v1/sql-workbench/explain","summary":"Explain SQL; ANALYZE remains subject to write gates","tag":"sql-workbench","pathParams":[],"queryParams":[],"bodyTypes":["application/json"],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchExportResult","method":"GET","path":"/qqq/v1/sql-workbench/executions/{uuid}/export","summary":"Export the caller's cached result as CSV, JSON or XLSX","tag":"sql-workbench","pathParams":["uuid"],"queryParams":["format"],"bodyTypes":[],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchGetCapabilities","method":"GET","path":"/qqq/v1/sql-workbench/capabilities","summary":"Get caller capabilities and configured limits","tag":"sql-workbench","pathParams":[],"queryParams":[],"bodyTypes":[],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchGetHistory","method":"GET","path":"/qqq/v1/sql-workbench/history","summary":"List the caller's recent audited executions","tag":"sql-workbench","pathParams":[],"queryParams":["limit","backendName"],"bodyTypes":[],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchGetNotebook","method":"GET","path":"/qqq/v1/sql-workbench/notebooks/{id}","summary":"Get a visible notebook and its cells","tag":"sql-workbench","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchGetRows","method":"GET","path":"/qqq/v1/sql-workbench/executions/{uuid}/rows","summary":"Page or sort the caller's cached result","tag":"sql-workbench","pathParams":["uuid"],"queryParams":["offset","limit","sort","dir"],"bodyTypes":[],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchGetSchema","method":"GET","path":"/qqq/v1/sql-workbench/schema/{backendName}","summary":"Inspect a target backend schema","tag":"sql-workbench","pathParams":["backendName"],"queryParams":["refresh"],"bodyTypes":[],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchGetVersion","method":"GET","path":"/qqq/v1/sql-workbench/notebooks/{id}/versions/{n}","summary":"Get a visible notebook version and saved content","tag":"sql-workbench","pathParams":["id","n"],"queryParams":[],"bodyTypes":[],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchListNotebooks","method":"GET","path":"/qqq/v1/sql-workbench/notebooks","summary":"List visible personal or shared notebooks","tag":"sql-workbench","pathParams":[],"queryParams":["scope"],"bodyTypes":[],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchListSnapshots","method":"GET","path":"/qqq/v1/sql-workbench/notebooks/{id}/snapshots","summary":"List snapshots of a visible notebook","tag":"sql-workbench","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchListVersions","method":"GET","path":"/qqq/v1/sql-workbench/notebooks/{id}/versions","summary":"List versions of a visible notebook","tag":"sql-workbench","pathParams":["id"],"queryParams":[],"bodyTypes":[],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchPublishNotebook","method":"POST","path":"/qqq/v1/sql-workbench/notebooks/{id}/publish","summary":"Publish or withdraw an owned notebook with share permission","tag":"sql-workbench","pathParams":["id"],"queryParams":[],"bodyTypes":["application/json"],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchRestoreVersion","method":"POST","path":"/qqq/v1/sql-workbench/notebooks/{id}/versions/{n}/restore","summary":"Restore an owned notebook version as a new version","tag":"sql-workbench","pathParams":["id","n"],"queryParams":[],"bodyTypes":["application/json"],"extension":"sql-workbench"}, + {"id":"sqlWorkbenchUpdateNotebook","method":"PUT","path":"/qqq/v1/sql-workbench/notebooks/{id}","summary":"Update an owned notebook and record a version","tag":"sql-workbench","pathParams":["id"],"queryParams":[],"bodyTypes":["application/json"],"extension":"sql-workbench"}, {"id":"stepProcess","method":"POST","path":"/qqq/v1/processes/{processName}/{processUUID}/step/{stepName}","summary":"Run a step in a process","tag":"Processes","pathParams":["processName","processUUID","stepName"],"queryParams":["tableVariant"],"bodyTypes":["multipart/form-data"]}, {"id":"storeAssociatedScript","method":"POST","path":"/qqq/v1/table/{tableName}/{primaryKey}/developer/associatedScript/{fieldName}","summary":"Store a new revision of a record's associated script (developer mode)","tag":"Tables","pathParams":["tableName","primaryKey","fieldName"],"queryParams":[],"bodyTypes":["application/json"]}, {"id":"suggestBulkLoadMapping","method":"POST","path":"/qqq/v1/bulkLoad/{tableName}/suggestMapping","summary":"Suggest a bulk load mapping for an uploaded file","tag":"Bulk Load","pathParams":["tableName"],"queryParams":[],"bodyTypes":["application/json"]}, diff --git a/packages/core/src/extensions/README.md b/packages/core/src/extensions/README.md new file mode 100644 index 0000000..89eaf97 --- /dev/null +++ b/packages/core/src/extensions/README.md @@ -0,0 +1,68 @@ +# Extensions in the kernel + +Extensions are the qbits and modules that add UI API operations (`/qqq/v1/qbit/{name}/...`, or an +established prefix such as `/esb`). The client document carries every extension found when it was +generated; a server has only some of them installed and lists them in `GET /version`. + +## Registry (`registry.ts`) + +```ts +import { extensionRegistry, KNOWN_EXTENSIONS, operationsOf, ExtensionNotInstalledError } from '@qrun-io/qqq-core' + +const registry = await extensionRegistry(server, authenticatedFetch) // GET /version, cached 5 min with the metadata +registry.has('collaboration') // installed at a version the client works with +registry.version('esb') // '1.1.0' | undefined +registry.require('collaboration') // throws ExtensionNotInstalledError: + // "extension collaboration is not installed on this server (installed: esb 1.1.0)" +registry.requireOperation(id) // same check for an operation id; core operations pass +registry.installed // every extension the server lists, `known: false` for ones the client lacks +registry.describe() // 'esb 1.1.0, zebra 0.3.0 (unknown to this client)' +``` + +- `KNOWN_EXTENSIONS`: name, label, path prefix, the version the document was generated from, + `minVersion` where the extension's docs state one (esb, health and collaboration 1.1.0), and + `channels`: the realtime channels it publishes on (collaboration: `record:{table}:{pk}`, + `table:{table}`, `user:me`). +- `operationsOf(name)` and `OperationInfo.extension` map operations to extensions. +- Unknown extensions are never dropped. An installed extension below `minVersion` gives + `has() === false` and `require()` throws with `reason: 'too-old'`. +- `ExtensionNotInstalledError` is the CLI's exit 5. The TUI should hide what `has()` denies + instead of showing the error. + +## Collaboration (`collaboration.ts`) + +```ts +const collab = new Collaboration(registry, { + call: (id, input) => callOperation(server, id, input, authenticatedFetch), + openStream: (signal) => openRealtimeStream({ baseUrl: server, signal, headers, token }), // optional +}) + +const presence = await collab.joinPresence({ table: 'person', pk: '1' }, { + onChange: (state) => draw(state.count, state.people), // people: [{ userId, name, mode, fieldName, since }] + mode: 'VIEWING', // or 'EDITING' (setMode('EDITING', 'email') while a field has focus) + announce: true, // false: watch without appearing +}) +presence.count; presence.people; presence.state.live; presence.state.error +await presence.stop() // DELETE /presence, stop the heartbeat, close the stream +``` + +- Without the extension `joinPresence` returns at once with `available: false`, nobody there, + and no requests; `stop()` is a no-op. A TUI can call it for every screen unconditionally. +- With it: POST `/presence` now and every 20 s (leases last 45 s), GET the snapshot, and, when + `openStream` is given, subscribe to `record:{t}:{pk}` or `table:{t}` on the stream's `hello` + and apply `presence.changed` events. Without a stream, each heartbeat re-reads the snapshot. + The stream reconnects with backoff (2 s doubling to 30 s) and re-reads on `resync`. +- `since` is when this client first saw the person; the qbit does not send join times. +- The list includes the signed-in user when they hold a lease (tabs and clients merge per user; + EDITING wins). +- One stream per joinPresence. A TUI that already holds a stream for other channels can pass an + `openStream` that fans out its own connection's events instead of opening another. +- `state.error` holds a refused heartbeat (404 when presence is off for the table or the record is + not visible). The heartbeat keeps trying. + +Other calls (all throw `ExtensionNotInstalledError` before any request when it is absent): +`favorites()`, `addFavorite(target)`, `removeFavorite(target)`, `recents(limit)`, +`recordView(target)`, `comments(table, pk, { cursor, limit })`, `addComment(table, pk, body, +{ parentCommentId, fieldName })`, `followState`, `follow(table, pk, prefs)`, `unfollow`, +`myWork()`, `people(q, limit)`, `presenceSnapshot(scope)` (empty when absent). Everything else the +qbit offers is reachable by operation id through `callOperation`. diff --git a/packages/core/src/extensions/collaboration.ts b/packages/core/src/extensions/collaboration.ts new file mode 100644 index 0000000..d94f418 --- /dev/null +++ b/packages/core/src/extensions/collaboration.ts @@ -0,0 +1,392 @@ +/* + * Copyright 2026 QRun.IO, Inc. + * Licensed under the Apache License, Version 2.0 (see LICENSE). + */ + +/** + * The collaboration extension (qbit-collaboration, `/qqq/v1/qbit/collaboration`) for both heads: + * live presence on a table or record, comments, favorites, recents, follow, people and my work. + * + * Presence follows the qbit's contract: a lease is renewed with POST /presence every 20 seconds + * (it expires after 45), DELETE /presence leaves, GET /presence is the snapshot, and + * `presence.changed` events carry the same snapshot on the `record:{table}:{pk}` and + * `table:{table}` realtime channels. Connection ids need not be stream connections, so a client + * without the stream still takes part by polling on each heartbeat. + * + * When the server does not have the extension, presence is a no-op (`available: false`, nobody + * there) and the other calls throw ExtensionNotInstalledError. + */ + +import type { RealtimeMessage } from '@qrun-io/qqq-ui-api-client' +import type { CallInput, CallResult } from '../api/call.js' +import type { ExtensionRegistry } from './registry.js' + +export const COLLABORATION = 'collaboration' + +/** How the module reaches the server: the kernel's callOperation, and optionally the realtime stream. */ +export interface CollaborationTransport { + call(id: string, input: CallInput): Promise + /** Opens GET /realtime/stream; without it presence is polled on each heartbeat. */ + openStream?(signal: AbortSignal): AsyncIterable +} + +/** A navigation target (favorites and recents). */ +export interface CollaborationTarget { + targetType: 'TABLE' | 'APP' | 'RECORD' | 'PROCESS' | 'REPORT' | 'SAVED_VIEW' + targetName: string + recordId?: string +} + +export interface FavoriteEntry { + id?: number + targetType?: string + targetName?: string + recordId?: string | null + label?: string + folder?: string | null + sortOrder?: number | null + available?: boolean + href?: string | null +} + +export interface CommentEntry { + id?: number + authorUserId?: string + authorDisplayName?: string + body?: string | null + createdAt?: string + editedAt?: string | null + resolvedAt?: string | null + deleted?: boolean + fieldName?: string | null + replies?: CommentEntry[] + [key: string]: unknown +} + +export interface CommentPage { + threads: CommentEntry[] + nextCursor?: string | null +} + +export interface FollowState { + following: boolean + follow?: { notifyOnChange?: boolean; notifyOnComment?: boolean; reason?: string; mutedUntil?: string | null } | null +} + +export interface PersonEntry { + userId?: string + displayName?: string + email?: string | null + lastSeenAt?: string | null +} + +export interface MyWork { + openTaskCount?: number + unreadMentionCount?: number + assignedRecordsByTable?: Record + tasks?: Record[] +} + +/** What presence is attached to: a table, or one record of it. */ +export interface PresenceScope { + table: string + pk?: string +} + +/** One person on the scope, merged across their tabs. */ +export interface PresencePerson { + userId: string + name: string + mode: 'VIEWING' | 'EDITING' | string + fieldName?: string | null + /** When this client first saw them there (the qbit does not send join times). */ + since: Date +} + +export interface PresenceState { + /** False when the server has no collaboration extension: nobody is ever shown. */ + available: boolean + scope: PresenceScope + count: number + people: PresencePerson[] + /** True while the realtime stream is connected and subscribed (else presence is polled). */ + live: boolean + /** The last error (presence not enabled on the table, record not visible, ...), cleared on success. */ + error?: string +} + +export interface PresenceOptions { + /** Called after every change of the state. */ + onChange?: (state: PresenceState) => void + /** VIEWING (default) or EDITING. */ + mode?: 'VIEWING' | 'EDITING' + fieldName?: string + /** Heartbeat period; default 20000 ms as the qbit asks. */ + heartbeatMs?: number + /** Connection id for the lease; default a random `cli-...` id. */ + connectionId?: string + /** False to only watch (snapshot plus events) without holding a lease. Default true. */ + announce?: boolean + /** Delay before reconnecting a dropped stream; default 2000 ms, doubling to 30 s. */ + reconnectMs?: number +} + +export interface PresenceHandle { + readonly state: PresenceState + readonly count: number + readonly people: PresencePerson[] + /** Re-reads the snapshot now. */ + refresh(): Promise + /** Changes mode or focused field and renews the lease at once. */ + setMode(mode: 'VIEWING' | 'EDITING', fieldName?: string): Promise + /** Leaves (DELETE /presence), stops the heartbeat and closes the stream. */ + stop(): Promise +} + +interface Viewer { + userId?: string + displayName?: string + mode?: string + fieldName?: string | null +} + +interface Snapshot { + table?: string + pk?: string | null + viewers?: Viewer[] +} + +/** The channel presence events for a scope arrive on. */ +export function presenceChannel(scope: PresenceScope): string { + return scope.pk !== undefined ? `record:${scope.table}:${scope.pk}` : `table:${scope.table}` +} + +function randomId(): string { + const bytes = new Uint8Array(8) + globalThis.crypto.getRandomValues(bytes) + return `cli-${Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')}` +} + +function messageOf(error: unknown): string { + return error instanceof Error ? error.message : String(error) +} + +/** The collaboration calls for one server; gated by its extension registry. */ +export class Collaboration { + constructor(private readonly registry: ExtensionRegistry, private readonly transport: CollaborationTransport) {} + + /** Whether the server has the extension (presence works, the other calls do not throw). */ + get available(): boolean { + return this.registry.has(COLLABORATION) + } + + private async data(id: string, input: CallInput = {}): Promise { + this.registry.require(COLLABORATION) + return (await this.transport.call(id, input)).data as T + } + + /** The signed-in user's favorites, in their order. */ + async favorites(): Promise { + return (await this.data<{ items?: FavoriteEntry[] }>('getQbitCollaborationFavorites')).items ?? [] + } + + /** Stars a target (idempotent). */ + async addFavorite(target: CollaborationTarget): Promise { + await this.data('putQbitCollaborationFavorites', { json: target }) + } + + /** Unstars a target (idempotent). */ + async removeFavorite(target: CollaborationTarget): Promise { + await this.data('deleteQbitCollaborationFavorites', { json: target }) + } + + /** Recently viewed targets, newest first (at most 50). */ + async recents(limit?: number): Promise { + return (await this.data<{ items?: FavoriteEntry[] }>('getQbitCollaborationRecents', { query: { limit: limit === undefined ? undefined : String(limit) } })).items ?? [] + } + + /** Records a view of a target (the server ignores repeats within a minute). */ + async recordView(target: CollaborationTarget): Promise { + await this.data('postQbitCollaborationRecents', { json: target }) + } + + /** A page of a record's comment threads, by latest activity, with replies. */ + async comments(table: string, pk: string, page: { cursor?: string; limit?: number } = {}): Promise { + const result = await this.data<{ threads?: CommentEntry[]; nextCursor?: string | null }>('getQbitCollaborationRecordsByTableByPkComments', { + path: { table, pk }, + query: { cursor: page.cursor, limit: page.limit === undefined ? undefined : String(page.limit) }, + }) + return { threads: result.threads ?? [], nextCursor: result.nextCursor ?? null } + } + + /** Posts a comment, or a reply with `parentCommentId`. Mentions are `@[Name](user:id)`. */ + async addComment(table: string, pk: string, body: string, options: { parentCommentId?: number; fieldName?: string } = {}): Promise { + return this.data('postQbitCollaborationRecordsByTableByPkComments', { path: { table, pk }, json: { body, ...options } }) + } + + /** The signed-in user's follow state on a record. */ + async followState(table: string, pk: string): Promise { + return this.data('getQbitCollaborationRecordsByTableByPkFollow', { path: { table, pk } }) + } + + /** Follows a record; omitted preferences keep their current values. */ + async follow(table: string, pk: string, preferences: { notifyOnChange?: boolean; notifyOnComment?: boolean } = {}): Promise { + return this.data('putQbitCollaborationRecordsByTableByPkFollow', { path: { table, pk }, json: preferences }) + } + + /** Stops following a record. */ + async unfollow(table: string, pk: string): Promise { + return this.data('deleteQbitCollaborationRecordsByTableByPkFollow', { path: { table, pk } }) + } + + /** Open tasks, assigned records per table and unread mentions of the signed-in user. */ + async myWork(): Promise { + return this.data('getQbitCollaborationMyWork') + } + + /** Searches the active people directory by name or email. */ + async people(q?: string, limit?: number): Promise { + return (await this.data<{ items?: PersonEntry[] }>('getQbitCollaborationPeople', { query: { q, limit: limit === undefined ? undefined : String(limit) } })).items ?? [] + } + + /** Who is on a table or record right now, without joining. Empty when the extension is absent. */ + async presenceSnapshot(scope: PresenceScope): Promise { + const state: PresenceState = { available: this.available, scope, count: 0, people: [], live: false } + if (!state.available) return state + const snapshot = (await this.transport.call('getQbitCollaborationPresence', { query: { table: scope.table, pk: scope.pk } })).data as Snapshot + const now = new Date() + state.people = (snapshot.viewers ?? []).map((v) => ({ userId: String(v.userId ?? ''), name: String(v.displayName ?? v.userId ?? ''), mode: v.mode ?? 'VIEWING', fieldName: v.fieldName ?? null, since: now })) + state.count = state.people.length + return state + } + + /** + * Joins presence on a table or record: holds a lease (unless `announce: false`), subscribes to + * the scope's realtime channel when a stream is available, and keeps `state` current. Returns + * at once with a no-op handle when the extension is absent. + */ + async joinPresence(scope: PresenceScope, options: PresenceOptions = {}): Promise { + const state: PresenceState = { available: this.available, scope, count: 0, people: [], live: false } + const notify = () => options.onChange?.({ ...state, people: [...state.people] }) + if (!state.available) { + return { state, get count() { return 0 }, get people() { return [] }, refresh: async () => {}, setMode: async () => {}, stop: async () => {} } + } + + const announce = options.announce !== false + const connectionId = options.connectionId ?? randomId() + const firstSeen = new Map() + let mode = options.mode ?? 'VIEWING' + let fieldName = options.fieldName + let stopped = false + const abort = new AbortController() + + const apply = (snapshot: Snapshot) => { + const now = new Date() + const viewers = (snapshot.viewers ?? []).filter((v) => v.userId !== undefined) + const ids = new Set(viewers.map((v) => String(v.userId))) + for (const id of [...firstSeen.keys()]) if (!ids.has(id)) firstSeen.delete(id) + state.people = viewers.map((v) => { + const userId = String(v.userId) + if (!firstSeen.has(userId)) firstSeen.set(userId, now) + return { userId, name: String(v.displayName ?? userId), mode: v.mode ?? 'VIEWING', fieldName: v.fieldName ?? null, since: firstSeen.get(userId)! } + }) + state.count = state.people.length + state.error = undefined + notify() + } + + const refresh = async () => { + try { + apply((await this.transport.call('getQbitCollaborationPresence', { query: { table: scope.table, pk: scope.pk } })).data as Snapshot) + } catch (error) { + state.error = messageOf(error) + notify() + } + } + + const heartbeat = async () => { + if (stopped) return + if (announce) { + try { + const result = await this.transport.call('postQbitCollaborationPresence', { json: { connectionId, table: scope.table, pk: scope.pk, mode, fieldName } }) + const data = result.data as Snapshot | undefined + // The qbit answers the heartbeat with the snapshot; older builds answer {success}. + if (data && typeof data.table === 'string') { + apply(data) + return + } + } catch (error) { + state.error = messageOf(error) + notify() + return + } + } + await refresh() + } + + const subscribe = async () => { + if (!this.transport.openStream) return + let delay = options.reconnectMs ?? 2000 + while (!stopped) { + try { + for await (const message of this.transport.openStream(abort.signal)) { + if (stopped) break + if (message.event === 'hello') { + const hello = (message.data ?? {}) as { connectionId?: string } + const result = await this.transport.call('updateRealtimeSubscriptions', { json: { connectionId: hello.connectionId, add: [presenceChannel(scope)] } }) + const active = ((result.data ?? {}) as { active?: string[] }).active ?? [] + state.live = active.includes(presenceChannel(scope)) + delay = options.reconnectMs ?? 2000 + await refresh() + } else if (message.event === 'presence.changed') { + // An emptied scope arrives as {"table": "person"} with no viewers at all. + const raw = message.data as Snapshot & { data?: Snapshot } + const snapshot = raw && typeof raw.table === 'string' ? raw : raw?.data + if (snapshot && snapshot.table === scope.table && (scope.pk === undefined ? snapshot.pk == null : String(snapshot.pk) === scope.pk)) apply(snapshot) + } else if (message.event === 'resync') { + await refresh() + } + } + } catch (error) { + if (stopped) break + state.error = messageOf(error) + } + if (stopped) break + state.live = false + notify() + await new Promise((resolve) => setTimeout(resolve, delay)) + delay = Math.min(delay * 2, 30000) + } + } + + await heartbeat() + const timer = setInterval(() => void heartbeat(), options.heartbeatMs ?? 20000) + void subscribe() + + return { + state, + get count() { return state.count }, + get people() { return state.people }, + refresh, + setMode: async (next, field) => { + mode = next + fieldName = field + await heartbeat() + }, + stop: async () => { + if (stopped) return + stopped = true + clearInterval(timer) + abort.abort() + state.live = false + if (announce) { + try { + await this.transport.call('deleteQbitCollaborationPresence', { json: { connectionId, table: scope.table, pk: scope.pk } }) + } catch { + // the lease expires on its own after 45 seconds + } + } + }, + } + } +} diff --git a/packages/core/src/extensions/registry.ts b/packages/core/src/extensions/registry.ts new file mode 100644 index 0000000..573397d --- /dev/null +++ b/packages/core/src/extensions/registry.ts @@ -0,0 +1,220 @@ +/* + * Copyright 2026 QRun.IO, Inc. + * Licensed under the Apache License, Version 2.0 (see LICENSE). + */ + +/** + * Extensions (qbits and modules that add UI API operations): which ones the client knows, which + * operations belong to each, and which ones a server has installed. The server's truth is + * GET /version `extensions`; the client's knowledge is the merged document it was generated from + * (DOCUMENT_EXTENSIONS and OperationInfo.extension) plus the facts below that the documents do not + * carry (documented minimum versions and the realtime channels an extension publishes on). + * + * Rules: an extension the server lists but the client does not know is kept and shown, never + * dropped; an operation of an extension the server does not list is refused before any request, + * with a message naming what is installed. + */ + +import { DOCUMENT_EXTENSIONS, OPERATIONS, operation, type OperationInfo } from '../api/operations.js' +import { getServerVersion, type MetaDataCacheOptions, type ServerVersion } from '../metadata/cache.js' + +/** What the client knows about one extension. */ +export interface KnownExtension { + name: string + /** Short human name, for headings. */ + label: string + /** The repository that publishes it. */ + repository: string + /** Path prefix under /qqq/v1 (`/qbit/{name}`, or an established one such as `/esb`). */ + pathPrefix: string + /** The extension version the client document was generated from. */ + documentVersion?: string + /** The lowest server version of this extension the client works with, when its docs state one. */ + minVersion?: string + /** The UI API version the extension's docs say it needs, when they say. */ + minUiApi?: string + /** Realtime channels (GET /realtime/stream subscriptions) the extension publishes events on. */ + channels: string[] + /** One line on what it does. */ + description: string +} + +/** One extension as the server lists it, joined with what the client knows. */ +export interface InstalledExtension { + name: string + version?: string + pathPrefix?: string + description?: string + /** False when the client has no document for it (it is still listed). */ + known: boolean + /** False when the client knows a minimum version and the server's is lower. */ + meetsMinimum: boolean +} + +interface Facts { + label: string + repository: string + minVersion?: string + minUiApi?: string + channels?: string[] +} + +/** + * Facts from each extension's own docs (README, UI-API-CHANGELOG.md) that the OpenAPI documents + * do not carry. Minimums are only set where the docs state one. + */ +const FACTS: Record = { + // UI-API-CHANGELOG.md: esb and health 1.1.0 added operationIds, tags and the standard errors. + esb: { label: 'ESB', repository: 'qqq (qqq-esb)', minVersion: '1.1.0' }, + health: { label: 'Health', repository: 'qqq (qqq-middleware-javalin)', minVersion: '1.1.0' }, + alerts: { label: 'Alerts', repository: 'qbit-alerts' }, + assistant: { label: 'Assistant', repository: 'qbit-assistant' }, + // qbit-collaboration README: 1.1.0 carries the UI API 1.6.0 error contract and the published + // presence schemas; it publishes on record:{table}:{pk}, table:{table} and user:{userId}. + collaboration: { label: 'Collaboration', repository: 'qbit-collaboration', minVersion: '1.1.0', minUiApi: '1.6.0', channels: ['record:{table}:{pk}', 'table:{table}', 'user:me'] }, + 'data-analysis': { label: 'Data analysis', repository: 'qbit-data-analysis' }, + 'db-performance': { label: 'DB performance', repository: 'qbit-db-performance' }, + edi: { label: 'EDI', repository: 'qbit-edi', minUiApi: '1.6.0' }, + 'qa-capture': { label: 'QA capture', repository: 'qbit-qa-capture' }, + 'quick-search': { label: 'Quick search', repository: 'qbit-quick-search' }, + 'release-notes': { label: 'Release notes', repository: 'qbit-release-notes' }, + 'secured-data': { label: 'Secured data', repository: 'qbit-secured-data', minUiApi: '1.6.0' }, + 'sql-workbench': { label: 'SQL workbench', repository: 'qbit-sql-workbench' }, +} + +/** Every extension the client has a document for, in document order. */ +export const KNOWN_EXTENSIONS: readonly KnownExtension[] = DOCUMENT_EXTENSIONS.map((e) => { + const facts: Facts = FACTS[e.name] ?? { label: e.name, repository: `qbit-${e.name}` } + return { + name: e.name, + label: facts.label, + repository: facts.repository, + pathPrefix: e.pathPrefix ?? `/qbit/${e.name}`, + documentVersion: e.version, + minVersion: facts.minVersion, + minUiApi: facts.minUiApi, + channels: facts.channels ?? [], + description: e.description ?? '', + } +}) + +const knownByName = new Map(KNOWN_EXTENSIONS.map((e) => [e.name, e])) + +/** What the client knows about an extension, or undefined. */ +export function knownExtension(name: string): KnownExtension | undefined { + return knownByName.get(name) +} + +/** The operations an extension serves, by id. */ +export function operationsOf(name: string): OperationInfo[] { + return OPERATIONS.filter((o) => o.extension === name) +} + +/** The extension an operation belongs to; undefined for core operations and unknown ids. */ +export function extensionOfOperation(id: string): string | undefined { + return operation(id)?.extension +} + +/** Compares two MAJOR.MINOR.PATCH versions (pre-release suffixes ignored). */ +export function compareVersions(a: string, b: string): number { + const parts = (v: string) => v.split(/[.+-]/).slice(0, 3).map((n) => Number.parseInt(n, 10) || 0) + const [x, y] = [parts(a), parts(b)] + for (let i = 0; i < 3; i++) if ((x[i] ?? 0) !== (y[i] ?? 0)) return (x[i] ?? 0) - (y[i] ?? 0) + return 0 +} + +/** Thrown when an operation or command needs an extension the server does not have (CLI exit 5). */ +export class ExtensionNotInstalledError extends Error { + readonly extension: string + readonly installed: InstalledExtension[] + /** `absent`, or `too-old` when the server has it below the client's minimum. */ + readonly reason: 'absent' | 'too-old' + + constructor(extension: string, installed: InstalledExtension[], reason: 'absent' | 'too-old' = 'absent', operationId?: string) { + const list = installed.length ? installed.map((e) => `${e.name}${e.version ? ` ${e.version}` : ''}`).join(', ') : 'none' + const subject = operationId ? `${operationId} belongs to extension ${extension}, which` : `extension ${extension}` + const found = installed.find((e) => e.name === extension) + const text = reason === 'too-old' + ? `${operationId ? `${operationId} needs` : 'this client needs'} extension ${extension} ${knownExtension(extension)?.minVersion} or later; this server has ${found?.version ?? 'an unknown version'} (installed: ${list})` + : `${subject} is not installed on this server (installed: ${list})` + super(text) + this.name = 'ExtensionNotInstalledError' + this.extension = extension + this.installed = installed + this.reason = reason + } +} + +/** Joins the server's GET /version `extensions` with the client's knowledge. Unknown ones are kept. */ +export function joinInstalled(version: ServerVersion): InstalledExtension[] { + return (version.extensions ?? []).filter((e) => e && typeof e.name === 'string').map((e) => { + const known = knownByName.get(e.name) + const meetsMinimum = !known?.minVersion || !e.version || compareVersions(e.version, known.minVersion) >= 0 + return { name: e.name, version: e.version, pathPrefix: e.pathPrefix, description: e.description, known: Boolean(known), meetsMinimum } + }) +} + +/** The extensions a server has installed, from its GET /version (cached with the metadata cache). */ +export async function installedExtensions(server: string, fetchImpl: typeof fetch, options: MetaDataCacheOptions & { offline?: boolean; refresh?: boolean } = {}): Promise { + return joinInstalled(await getServerVersion(server, fetchImpl, options)) +} + +/** One server's extensions: what is installed, and the checks commands make before calling. */ +export class ExtensionRegistry { + readonly installed: InstalledExtension[] + private readonly byName: Map + + constructor(installed: InstalledExtension[]) { + this.installed = installed + this.byName = new Map(installed.map((e) => [e.name, e])) + } + + /** A registry from a GET /version document. */ + static fromVersion(version: ServerVersion): ExtensionRegistry { + return new ExtensionRegistry(joinInstalled(version)) + } + + /** Whether the server has the extension at a version the client works with. */ + has(name: string): boolean { + const e = this.byName.get(name) + return Boolean(e && e.meetsMinimum) + } + + /** The installed version of an extension, or undefined. */ + version(name: string): string | undefined { + return this.byName.get(name)?.version + } + + /** The installed extension, or a typed error naming what is installed. */ + require(name: string): InstalledExtension { + const e = this.byName.get(name) + if (!e) throw new ExtensionNotInstalledError(name, this.installed, 'absent') + if (!e.meetsMinimum) throw new ExtensionNotInstalledError(name, this.installed, 'too-old') + return e + } + + /** Throws when the operation belongs to an extension this server does not have; core operations pass. */ + requireOperation(id: string): void { + const name = extensionOfOperation(id) + if (!name) return + const e = this.byName.get(name) + if (!e) throw new ExtensionNotInstalledError(name, this.installed, 'absent', id) + if (!e.meetsMinimum) throw new ExtensionNotInstalledError(name, this.installed, 'too-old', id) + } + + /** Installed extensions the client has no document for (tolerated and listed). */ + unknown(): InstalledExtension[] { + return this.installed.filter((e) => !e.known) + } + + /** `esb 1.1.0, foo 2.0.0 (unknown to this client)`, or `none`. */ + describe(): string { + if (!this.installed.length) return 'none' + return this.installed.map((e) => `${e.name}${e.version ? ` ${e.version}` : ''}${e.known ? '' : ' (unknown to this client)'}${e.meetsMinimum ? '' : ` (below ${knownExtension(e.name)?.minVersion})`}`).join(', ') + } +} + +/** The registry of a server, from its cached GET /version. */ +export async function extensionRegistry(server: string, fetchImpl: typeof fetch, options: MetaDataCacheOptions & { offline?: boolean; refresh?: boolean } = {}): Promise { + return new ExtensionRegistry(await installedExtensions(server, fetchImpl, options)) +} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index f467a94..0017497 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -31,3 +31,5 @@ export * from './forms/datetime.js' export * from './records/associations.js' export * from './records/record-view.js' export * from './render/files.js' +export * from './extensions/registry.js' +export * from './extensions/collaboration.js' diff --git a/packages/core/src/metadata/cache.ts b/packages/core/src/metadata/cache.ts index 0d6a6d6..8f9ed06 100644 --- a/packages/core/src/metadata/cache.ts +++ b/packages/core/src/metadata/cache.ts @@ -70,7 +70,10 @@ export function writeCachedMetaData(server: string, metaData: MetaDataDocument, /** Removes the cache of one server, or of every server. */ export function clearMetaDataCache(server?: string, options: MetaDataCacheOptions = {}): void { const dir = options.dir ?? defaultDir() - if (server) rmSync(fileFor(dir, server), { force: true }) + if (server) { + rmSync(fileFor(dir, server), { force: true }) + rmSync(versionFileFor(dir, server), { force: true }) + } else rmSync(dir, { recursive: true, force: true }) } @@ -85,7 +88,8 @@ export async function getMetaData(server: string, fetchImpl: typeof fetch, optio if (options.offline && !cached) throw new Error('No cached metadata for this server; run any qqq command once to fill the cache.') let version: string | undefined try { - const v = (await callOperation(server, 'getVersion', {}, fetchImpl)).data as { apiVersion?: string } + const v = (await callOperation(server, 'getVersion', {}, fetchImpl)).data as ServerVersion + writeCachedVersion(server, v, options) version = v.apiVersion } catch (error) { if (cached) return cached.metaData @@ -133,3 +137,50 @@ export async function getTableMetaData(server: string, table: strin writeCachedTableMeta(server, table, metaData, options) return metaData } + +/** GET /version: the API semver, core features, registered extensions and accepted client channels. */ +export interface ServerVersion { + apiVersion?: string + basePath?: string + supportedMajorVersions?: number[] + features?: string[] + extensions?: { name: string; version?: string; pathPrefix?: string; description?: string }[] + clientChannels?: string[] + [key: string]: unknown +} + +function versionFileFor(dir: string, server: string): string { + return join(dir, `version-${server.replace(/[^A-Za-z0-9.-]+/g, '_')}.json`) +} + +function writeCachedVersion(server: string, version: ServerVersion, options: MetaDataCacheOptions = {}): void { + const dir = options.dir ?? defaultDir() + mkdirSync(dir, { recursive: true, mode: 0o700 }) + writeFileSync(versionFileFor(dir, server), JSON.stringify({ fetchedAt: new Date().toISOString(), version }), { mode: 0o600 }) +} + +/** + * The server's GET /version, cached next to its metadata with the same TTL (it is unsecured and + * small, but listings and completion should not wait for it). `offline` uses a stale copy. + */ +export async function getServerVersion(server: string, fetchImpl: typeof fetch, options: MetaDataCacheOptions & { offline?: boolean; refresh?: boolean } = {}): Promise { + const file = versionFileFor(options.dir ?? defaultDir(), server) + let cached: { fetchedAt: string; version: ServerVersion } | undefined + if (!options.refresh && existsSync(file)) { + try { + cached = JSON.parse(readFileSync(file, 'utf8')) as { fetchedAt: string; version: ServerVersion } + } catch { + cached = undefined + } + } + if (cached && (options.offline || Date.now() - Date.parse(cached.fetchedAt) < (options.ttlSeconds ?? 300) * 1000)) return cached.version + if (options.offline && !cached) throw new Error('No cached version for this server; run any qqq command once to fill the cache.') + try { + const version = (await callOperation(server, 'getVersion', {}, fetchImpl)).data as ServerVersion + writeCachedVersion(server, version, options) + return version + } catch (error) { + if (cached) return cached.version + throw error + } +} diff --git a/packages/core/src/test/collaboration.test.ts b/packages/core/src/test/collaboration.test.ts new file mode 100644 index 0000000..2634f9e --- /dev/null +++ b/packages/core/src/test/collaboration.test.ts @@ -0,0 +1,130 @@ +/* + * Copyright 2026 QRun.IO, Inc. + * Licensed under the Apache License, Version 2.0 (see LICENSE). + */ + +import assert from 'node:assert/strict' +import { test } from 'node:test' +import type { RealtimeMessage } from '@qrun-io/qqq-ui-api-client' +import type { CallInput, CallResult } from '../api/call.js' +import { Collaboration, presenceChannel, type CollaborationTransport, type PresenceState } from '../extensions/collaboration.js' +import { ExtensionNotInstalledError, ExtensionRegistry } from '../extensions/registry.js' + +const withCollab = ExtensionRegistry.fromVersion({ extensions: [{ name: 'collaboration', version: '1.1.0' }] }) +const without = ExtensionRegistry.fromVersion({ extensions: [{ name: 'esb', version: '1.1.0' }] }) +const result = (data: unknown): CallResult => ({ status: 200, headers: new Headers(), data, contentType: 'application/json' }) +const tick = (ms = 5) => new Promise((resolve) => setTimeout(resolve, ms)) + +/** A fake server: records calls, answers from a handler. */ +function fake(handler: (id: string, input: CallInput) => unknown, stream?: (signal: AbortSignal) => AsyncIterable) { + const calls: { id: string; input: CallInput }[] = [] + const transport: CollaborationTransport = { + call: async (id, input) => { + calls.push({ id, input }) + return result(handler(id, input)) + }, + openStream: stream, + } + return { calls, transport } +} + +test('without the extension, presence is a no-op and other calls throw the typed error before any request', async () => { + const { calls, transport } = fake(() => ({})) + const collab = new Collaboration(without, transport) + assert.equal(collab.available, false) + const handle = await collab.joinPresence({ table: 'person', pk: '1' }) + assert.deepEqual([handle.count, handle.people, handle.state.available], [0, [], false]) + await handle.stop() + assert.equal((await collab.presenceSnapshot({ table: 'person' })).count, 0) + await assert.rejects(collab.favorites(), (e: unknown) => e instanceof ExtensionNotInstalledError && /installed: esb 1\.1\.0/.test(e.message)) + assert.equal(calls.length, 0) +}) + +test('favorites, recents, comments, follow, people and my work call the qbit operations', async () => { + const { calls, transport } = fake((id) => { + if (id === 'getQbitCollaborationFavorites') return { items: [{ id: 1, targetType: 'RECORD', targetName: 'person', recordId: '1', label: 'Avery' }], nextCursor: null } + if (id === 'getQbitCollaborationRecordsByTableByPkComments') return { threads: [{ id: 5, body: 'hi' }], nextCursor: 'c2' } + if (id === 'postQbitCollaborationRecordsByTableByPkComments') return { id: 6, body: 'new' } + if (id.includes('Follow')) return { following: id !== 'deleteQbitCollaborationRecordsByTableByPkFollow' } + if (id === 'getQbitCollaborationPeople') return { items: [{ userId: 'bob', displayName: 'Bob Chen' }] } + if (id === 'getQbitCollaborationMyWork') return { openTaskCount: 2, unreadMentionCount: 1 } + return { items: [], success: true } + }) + const collab = new Collaboration(withCollab, transport) + assert.equal((await collab.favorites())[0]?.label, 'Avery') + await collab.addFavorite({ targetType: 'RECORD', targetName: 'person', recordId: '1' }) + await collab.removeFavorite({ targetType: 'TABLE', targetName: 'person' }) + await collab.recents(10) + assert.deepEqual(await collab.comments('person', '1', { limit: 5 }), { threads: [{ id: 5, body: 'hi' }], nextCursor: 'c2' }) + assert.equal((await collab.addComment('person', '1', 'new', { parentCommentId: 5 })).id, 6) + assert.equal((await collab.follow('person', '1', { notifyOnComment: true })).following, true) + assert.equal((await collab.unfollow('person', '1')).following, false) + assert.equal((await collab.people('bo'))[0]?.displayName, 'Bob Chen') + assert.equal((await collab.myWork()).openTaskCount, 2) + const byId = Object.fromEntries(calls.map((c) => [c.id, c.input])) + assert.deepEqual(byId.putQbitCollaborationFavorites, { json: { targetType: 'RECORD', targetName: 'person', recordId: '1' } }) + assert.deepEqual(byId.getQbitCollaborationRecents, { query: { limit: '10' } }) + assert.deepEqual(byId.postQbitCollaborationRecordsByTableByPkComments, { path: { table: 'person', pk: '1' }, json: { body: 'new', parentCommentId: 5 } }) + assert.deepEqual(byId.getQbitCollaborationPeople, { query: { q: 'bo', limit: undefined } }) +}) + +test('joinPresence holds a lease, polls on each heartbeat without a stream, tracks since, and leaves on stop', async () => { + let viewers = [{ userId: 'bob', displayName: 'Bob Chen', mode: 'VIEWING' }] + const { calls, transport } = fake((id) => (id === 'deleteQbitCollaborationPresence' ? { success: true } : { table: 'person', pk: '1', viewers })) + const states: PresenceState[] = [] + const handle = await new Collaboration(withCollab, transport).joinPresence({ table: 'person', pk: '1' }, { heartbeatMs: 20, connectionId: 'cli-test', onChange: (s) => states.push(s) }) + assert.equal(handle.count, 1) + const bobSince = handle.people[0]!.since + viewers = [...viewers, { userId: 'carol', displayName: 'Carol', mode: 'EDITING' }] + await tick(35) + assert.deepEqual(handle.people.map((p) => [p.name, p.mode]), [['Bob Chen', 'VIEWING'], ['Carol', 'EDITING']]) + assert.equal(handle.people[0]!.since, bobSince) + await handle.stop() + const posts = calls.filter((c) => c.id === 'postQbitCollaborationPresence') + assert.ok(posts.length >= 2) + assert.deepEqual(posts[0]!.input.json, { connectionId: 'cli-test', table: 'person', pk: '1', mode: 'VIEWING', fieldName: undefined }) + assert.deepEqual(calls.at(-1), { id: 'deleteQbitCollaborationPresence', input: { json: { connectionId: 'cli-test', table: 'person', pk: '1' } } }) + const after = calls.length + await tick(30) + assert.equal(calls.length, after, 'no heartbeat after stop') + assert.ok(states.length >= 2) +}) + +test('joinPresence subscribes the scope channel on hello and applies presence.changed for its scope only', async () => { + const events: RealtimeMessage[] = [ + { event: 'hello', data: { connectionId: 'sse-1', heartbeatSeconds: 25 } }, + { event: 'presence.changed', data: { table: 'person', viewers: [{ userId: 'zed', displayName: 'Zed' }] } }, + { event: 'presence.changed', data: { table: 'person', pk: '1', viewers: [{ userId: 'bob', displayName: 'Bob Chen', mode: 'EDITING', fieldName: 'email' }] } }, + ] + const emptied: RealtimeMessage = { event: 'presence.changed', data: { table: 'person', pk: '1' } } + async function* stream(signal: AbortSignal): AsyncIterable { + let next = 0 + while (!signal.aborted) { + await tick(2) + if (next < events.length) yield events[next++]! + } + } + const { calls, transport } = fake((id, input) => { + if (id === 'updateRealtimeSubscriptions') return { active: (input.json as { add: string[] }).add, refused: [] } + if (id === 'deleteQbitCollaborationPresence') return { success: true } + return { table: 'person', pk: '1', viewers: [] } + }, stream) + const handle = await new Collaboration(withCollab, transport).joinPresence({ table: 'person', pk: '1' }, { announce: false, heartbeatMs: 10000 }) + await tick(30) + assert.deepEqual(calls.find((c) => c.id === 'updateRealtimeSubscriptions')?.input.json, { connectionId: 'sse-1', add: ['record:person:1'] }) + assert.equal(handle.state.live, true) + assert.deepEqual(handle.people.map((p) => [p.userId, p.mode, p.fieldName]), [['bob', 'EDITING', 'email']]) + events.push(emptied) + await tick(10) + assert.equal(handle.count, 0, 'a snapshot without viewers empties the scope (the qbit omits the empty list)') + await handle.stop() + assert.equal(calls.some((c) => c.id === 'postQbitCollaborationPresence' || c.id === 'deleteQbitCollaborationPresence'), false, 'watch-only never takes a lease') + assert.equal(presenceChannel({ table: 'person' }), 'table:person') +}) + +test('a refused heartbeat is reported as the state error', async () => { + const transport: CollaborationTransport = { call: async (id) => { if (id === 'postQbitCollaborationPresence') throw new Error('Not found'); return result({ success: true }) } } + const handle = await new Collaboration(withCollab, transport).joinPresence({ table: 'secret' }, { heartbeatMs: 10000 }) + assert.equal(handle.state.error, 'Not found') + await handle.stop() +}) diff --git a/packages/core/src/test/extensions.test.ts b/packages/core/src/test/extensions.test.ts new file mode 100644 index 0000000..892d562 --- /dev/null +++ b/packages/core/src/test/extensions.test.ts @@ -0,0 +1,70 @@ +/* + * Copyright 2026 QRun.IO, Inc. + * Licensed under the Apache License, Version 2.0 (see LICENSE). + */ + +import assert from 'node:assert/strict' +import { mkdtempSync, rmSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { test } from 'node:test' +import { OPERATIONS, operation } from '../api/operations.js' +import { ExtensionNotInstalledError, ExtensionRegistry, KNOWN_EXTENSIONS, compareVersions, extensionOfOperation, installedExtensions, knownExtension, operationsOf } from '../extensions/registry.js' + +const json = (body: unknown) => new Response(JSON.stringify(body), { status: 200, headers: { 'content-type': 'application/json' } }) + +test('every extension operation in the index names its extension; core operations name none', () => { + assert.equal(operation('getEsbOverview')?.extension, 'esb') + assert.equal(operation('getQbitCollaborationPresence')?.extension, 'collaboration') + assert.equal(operation('queryTable')?.extension, undefined) + for (const e of KNOWN_EXTENSIONS) assert.ok(operationsOf(e.name).length > 0, `${e.name} has operations`) + const names = new Set(KNOWN_EXTENSIONS.map((e) => e.name)) + for (const o of OPERATIONS) if (o.extension) assert.ok(names.has(o.extension), `${o.id} -> ${o.extension}`) + for (const name of ['esb', 'health', 'alerts', 'assistant', 'collaboration', 'data-analysis', 'sql-workbench', 'secured-data', 'edi', 'quick-search', 'qa-capture']) assert.ok(knownExtension(name), name) + assert.equal(knownExtension('collaboration')?.pathPrefix, '/qbit/collaboration') + assert.deepEqual(knownExtension('collaboration')?.channels, ['record:{table}:{pk}', 'table:{table}', 'user:me']) + assert.equal(extensionOfOperation('getQbitEdiGuidesByGuideIdTree') ?? extensionOfOperation(operationsOf('edi')[0]!.id), 'edi') +}) + +test('the registry knows what is installed, keeps unknown extensions, and refuses absent ones with the installed list', () => { + const registry = ExtensionRegistry.fromVersion({ apiVersion: '1.8.0', extensions: [{ name: 'esb', version: '1.1.0' }, { name: 'zebra', version: '0.3.0' }] }) + assert.equal(registry.has('esb'), true) + assert.equal(registry.has('collaboration'), false) + assert.equal(registry.version('esb'), '1.1.0') + assert.deepEqual(registry.unknown().map((e) => e.name), ['zebra']) + assert.equal(registry.describe(), 'esb 1.1.0, zebra 0.3.0 (unknown to this client)') + assert.throws(() => registry.require('collaboration'), (e: unknown) => e instanceof ExtensionNotInstalledError && e.message === 'extension collaboration is not installed on this server (installed: esb 1.1.0, zebra 0.3.0)' && e.reason === 'absent') + assert.doesNotThrow(() => registry.requireOperation('queryTable')) + assert.doesNotThrow(() => registry.requireOperation('getEsbOverview')) + assert.throws(() => registry.requireOperation('getQbitCollaborationMyWork'), /getQbitCollaborationMyWork belongs to extension collaboration, which is not installed on this server \(installed: esb 1\.1\.0/) + assert.throws(() => new ExtensionRegistry([]).require('esb'), /\(installed: none\)/) +}) + +test('an installed extension below the documented minimum is not usable', () => { + const registry = ExtensionRegistry.fromVersion({ extensions: [{ name: 'collaboration', version: '1.0.3' }] }) + assert.equal(registry.has('collaboration'), false) + assert.throws(() => registry.require('collaboration'), (e: unknown) => e instanceof ExtensionNotInstalledError && e.reason === 'too-old' && /1\.1\.0 or later; this server has 1\.0\.3/.test(e.message)) + assert.ok(compareVersions('1.10.0', '1.9.9') > 0) + assert.equal(compareVersions('1.1.0-RC.2', '1.1.0'), 0) +}) + +test('installedExtensions reads GET /version once and serves it from the cache', async () => { + const dir = mkdtempSync(join(tmpdir(), 'qqq-ext-')) + let calls = 0 + const fetchImpl: typeof fetch = async () => { + calls++ + return json({ apiVersion: '1.8.0', extensions: [{ name: 'esb', version: '1.1.0', pathPrefix: '/esb' }] }) + } + try { + const first = await installedExtensions('http://h', fetchImpl, { dir }) + assert.deepEqual(first, [{ name: 'esb', version: '1.1.0', pathPrefix: '/esb', description: undefined, known: true, meetsMinimum: true }]) + await installedExtensions('http://h', fetchImpl, { dir }) + assert.equal(calls, 1) + await installedExtensions('http://h', fetchImpl, { dir, refresh: true }) + assert.equal(calls, 2) + const offline = await installedExtensions('http://h', async () => { throw new Error('down') }, { dir, ttlSeconds: 0 }) + assert.equal(offline[0]?.name, 'esb') + } finally { + rmSync(dir, { recursive: true, force: true }) + } +}) diff --git a/packages/ui-api-client/openapi/extension-sources.json b/packages/ui-api-client/openapi/extension-sources.json new file mode 100644 index 0000000..c97df80 --- /dev/null +++ b/packages/ui-api-client/openapi/extension-sources.json @@ -0,0 +1,96 @@ +{ + "core": "http://localhost:8077/qqq/v1/openapi.json", + "extensions": [ + { + "name": "esb", + "version": "1.1.0", + "document": ".worktrees/qqq-develop/qqq-esb/src/main/resources/openapi/qqq-v1/esb.yaml", + "branch": "HEAD", + "commit": "6ac64fc66" + }, + { + "name": "health", + "version": "1.1.0", + "document": ".worktrees/qqq-develop/qqq-middleware-javalin/src/main/resources/openapi/qqq-v1/health.yaml", + "branch": "HEAD", + "commit": "6ac64fc66" + }, + { + "name": "alerts", + "version": "1.2.0", + "document": "qbit-alerts/src/main/resources/openapi/qqq-v1/alerts.yaml", + "branch": "develop", + "commit": "a3fc6ac" + }, + { + "name": "assistant", + "version": "1.6.0", + "document": "qbit-assistant/qbit-assistant/src/main/resources/openapi/qqq-v1/assistant.yaml", + "branch": "develop", + "commit": "bcf173f" + }, + { + "name": "collaboration", + "version": "1.1.0", + "document": "qbit-collaboration/src/main/resources/openapi/qqq-v1/collaboration.yaml", + "branch": "develop", + "commit": "03407ae" + }, + { + "name": "data-analysis", + "version": "1.5.0", + "document": "qbit-data-analysis/src/main/resources/openapi/qqq-v1/data-analysis.yaml", + "branch": "develop", + "commit": "368d2c0" + }, + { + "name": "db-performance", + "version": "1.0.0", + "document": "qbit-db-performance/src/main/resources/openapi/qqq-v1/db-performance.yaml", + "branch": "develop", + "commit": "4fd2c30" + }, + { + "name": "edi", + "version": "1.1.0", + "document": "qbit-edi/src/main/resources/openapi/qqq-v1/edi.yaml", + "branch": "develop", + "commit": "75a4e6b" + }, + { + "name": "qa-capture", + "version": "1.0.0", + "document": "qbit-qa-capture/src/main/resources/openapi/qqq-v1/qa-capture.yaml", + "branch": "develop", + "commit": "1aee6cb" + }, + { + "name": "quick-search", + "version": "1.1.0", + "document": "qbit-quick-search/src/main/resources/openapi/qqq-v1/quick-search.yaml", + "branch": "develop", + "commit": "bd50e1f" + }, + { + "name": "release-notes", + "version": "1.0.0", + "document": "qbit-release-notes/src/main/resources/openapi/qqq-v1/release-notes.yaml", + "branch": "develop", + "commit": "8fed18e" + }, + { + "name": "secured-data", + "version": "1.1.0", + "document": "qbit-secured-data/src/main/resources/openapi/qqq-v1/secured-data.yaml", + "branch": "develop", + "commit": "7b302ed" + }, + { + "name": "sql-workbench", + "version": "1.1.0", + "document": "qbit-sql-workbench/src/main/resources/openapi/qqq-v1/sql-workbench.yaml", + "branch": "develop", + "commit": "a182076" + } + ] +} diff --git a/packages/ui-api-client/openapi/qqq-v1.json b/packages/ui-api-client/openapi/qqq-v1.json index 320674d..1eb6648 100644 --- a/packages/ui-api-client/openapi/qqq-v1.json +++ b/packages/ui-api-client/openapi/qqq-v1.json @@ -1 +1,44506 @@ -{"openapi":"3.0.3","info":{"title":"QQQ Middleware API","description":"## Intro\nThis is the definition of the standard API implemented by QQQ Middleware.\n\nDevelopers of QQQ Frontends (e.g., javascript libraries, or native applications) use this API to access\na QQQ Backend server.\n\nAs such, this API itself is not concerned with any of the application-level details of any particular\napplication built using QQQ. Instead, this API is all about the generic endpoints used for any application\nbuilt on QQQ. For example, many endpoints work with a `${table}` path parameter - whose possible values\nare defined by the application - but which are not known to this API.\n\n## Flow\nThe typical flow of a user (as implemented in a frontend that utilizes this API) looks like:\n1. Frontend calls `.../metaData/authentication`, to know what type of authentication provider is used by the backend, and display an appropriate UI to the user for authenticating.\n2. User authenticates in frontend, as required for the authentication provider.\n3. Frontend calls `.../manageSession`, providing authentication details (e.g., an accessToken or other credentials) to the backend.\n4. The response from the `manageSession` call (assuming success), sets the `sessionUUID` Cookie, which should be included in all subsequent requests for authentication.\n5. After the user is authenticated, the frontend calls `.../metaData`, to discover the apps, tables, processes, etc, that the application is made up of (and that the authenticated user has permission to access).\n6. As the user interacts with apps, tables, process, etc, the frontend utilizes the appropriate endpoints as required.\n\n## Client channel\nEvery request should name its client in the `X-QQQ-Client` header: `channel[/detail]`, e.g. `next-ui`, `cli`,\nor `assistant/` (the accepted channels are listed by `GET .../version`; an unknown one is refused with 400).\nThe channel is recorded in audits. It is attribution only: the actor is always the signed-in user, and a channel\nnever grants anything - but some objects are denied to some channels (e.g. the AI assistant can never see its own\nconfiguration, identity and permission administration, audits, API keys or secrets), exactly as if the user had\nno permission for them.\n","contact":{"email":"contact@kingsrook.com"},"version":"1.8.0"},"servers":[{"description":"The QQQ server that serves this document (paths include /qqq/v1).","url":"/"}],"tags":[{"name":"Authentication"},{"name":"Bulk Load"},{"name":"ESB"},{"name":"General"},{"name":"Processes"},{"name":"Reports"},{"name":"Tables"},{"name":"Widgets"}],"paths":{"/qqq/v1/version":{"get":{"summary":"Get the UI API version","description":"Describes the semantic version of this UI API (MAJOR.MINOR.PATCH, where MAJOR matches the URL\nversion), the optional core features the server supports, and the extensions (modules and qbits)\nregistered on it, each with its own semantic version.\n\nA client should call this first, before authentication, and stop with a clear message when\napiVersion is outside the range it supports. Not secured.","operationId":"getVersion","tags":["General"],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionResponseV1"},"examples":{"Server with one extension":{"value":{"apiVersion":"1.1.0","basePath":"/qqq/v1","supportedMajorVersions":[1],"features":["recordSearch","tableVariants","version"],"extensions":[{"name":"esb","version":"1.0.0","pathPrefix":"/esb","description":"ESB overview, destinations, messages and dead letters"}]}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}}}},"/qqq/v1/realtime/stream":{"get":{"summary":"Open the realtime event stream","description":"SSE invalidation hints. Each event has id :, an event name and JSON data. hello identifies the connection; comment pings maintain it. Last-Event-ID replays retained events on the same pod and session, otherwise resync asks clients to refetch. Core event payloads use the Realtime*EventV1 components. job.progress uses RealtimeJobProgressEventV1; an advancing logSeq tells clients to poll the job log. Qbits publish through RealtimeBus with their own event names, such as presence.changed and comment.added, described by RealtimeEventV1. Subscriptions require a separate POST; session-ended closes the stream and channel-revoked removes a subscription.","operationId":"openRealtimeStream","tags":["General"],"parameters":[{"name":"Last-Event-ID","description":"Last received : cursor.","required":false,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":"Realtime named events and comment heartbeats.","content":{"text/event-stream":{"schema":{"$ref":"#/components/schemas/RealtimeEventV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/realtime/subscriptions":{"post":{"summary":"Change realtime subscriptions","description":"Add or remove record:{table}:{pk}, table:{table}, user:me, or instance channels. Records require a permission-checked GetAction and tables require READ. Refusals give no reason. The connection must belong to the authenticated session; otherwise 404. Active user channels are returned as user:me. Channel limits apply.","operationId":"updateRealtimeSubscriptions","tags":["General"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"add":{"type":"array","items":{"type":"string"}},"connectionId":{"type":"string"},"remove":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"400":{"description":"Malformed subscription request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Connection not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"200":{"description":"Current subscriptions and refused additions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RealtimeSubscriptionResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/metaData/authentication":{"get":{"summary":"Get authentication metaData","description":"For a frontend to determine which authentication provider or mechanism to use, it should begin its lifecycle\nby requesting this metaData object, and inspecting the `type` property in the response.\n\nNote that this endpoint is not secured, as its purpose is to be called as part of the workflow that results\nin a user being authenticated.","operationId":"getAuthenticationMetaData","tags":["Authentication"],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationMetaDataResponseV1"},"examples":{"For FULLY_ANONYMOUS type":{"value":{"type":"FULLY_ANONYMOUS","name":"anonymous"}},"For AUTH_0 type":{"value":{"type":"AUTH_0","name":"auth0","values":{"clientId":"abcdefg1234567","baseUrl":"https://myapp.auth0.com/","audience":"myapp.mydomain.com"}}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}}}},"/qqq/v1/branding/{role}":{"get":{"summary":"Get a branding image","description":"The image the app declares for a branding role (`logo` or `icon`), from the application's\nstatic overlay, available before sign-in. 404 when the app declares none for the role, or\ndeclares a data: URI or an external URL (those are in `branding` of GET /metaData/authentication).\nSince 1.6.0.","operationId":"getBrandingAsset","tags":["Authentication"],"parameters":[{"name":"role","description":"logo or icon.","required":true,"in":"path","schema":{"type":"string","enum":["logo","icon"]}}],"responses":{"200":{"description":"The image (png, jpeg, gif, webp, avif, ico or svg).","content":{"image/*":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}}}},"/qqq/v1/avatars/lookup":{"post":{"summary":"Look up users' avatars","description":"The avatar URL (GET /avatars/{avatarId}, with its version) of each user id given, for any signed-in user.\nUsers without an avatar are not in the result: draw their initials. At most 200 ids per call. Since 1.8.0.","operationId":"lookupAvatars","tags":["Authentication"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvatarLookupRequestV1"}}}},"responses":{"200":{"description":"The avatar URLs of the users that have one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvatarLookupResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/avatars/{avatarId}":{"get":{"summary":"Get an avatar","description":"An avatar as a square PNG, by its opaque id, for any signed-in user. 404 when there is none (draw initials).\nAvatar URLs come from POST /avatars/lookup (other users), `values.user.avatarUrl` of POST /manageSession and\nthe `profile` preferences section (the signed-in user). A user's chosen Gravatar is fetched and re-encoded by\nthe server, so browsers never contact Gravatar. With `v` equal to the current version the response is\ncacheable for a year; otherwise for five minutes, with an ETag. Since 1.8.0.","operationId":"getAvatar","tags":["Authentication"],"parameters":[{"name":"avatarId","description":"The avatar's opaque id (from an avatar URL).","required":true,"in":"path","schema":{"type":"string"}},{"name":"size","description":"Edge in pixels: 32, 64, 128 or 256 (default 128).","required":false,"in":"query","schema":{"type":"integer"}},{"name":"v","description":"The avatar's version, from an avatarUrl; makes the response cacheable for a year.","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"The avatar (PNG).","content":{"image/png":{"schema":{"type":"string","format":"binary"}}}},"304":{"description":"Not modified (If-None-Match matched the ETag)."},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/manageSession":{"post":{"summary":"Create a session","description":"After a frontend authenticates the user as per the requirements of the authentication provider specified by the\n`type` field in the `metaData/authentication` response, data from that authentication provider should be posted\nto this endpoint, to create a session within the QQQ application.\n\nThe response object will include a session identifier (`uuid`) to authenticate the user in subsequent API calls.\n\nFor the `TABLE_BASED` type, send the user's credentials in an `Authorization: Basic` header (base64 of\n`username:password`, UTF-8); the body may be empty. The password is verified against the user table and a\nsession row is stored; a `401` response means the credentials were refused.\n\nTo resume the session the browser already holds (for example after a page reload), post an empty object:\na request with no credentials and no `sessionUUID` resumes the session named by the `sessionUUID` cookie,\nwhich may be `HttpOnly`. That response carries the session's `values` but not its `uuid`; a `401`\nresponse means there is no valid session to resume.","operationId":"manageSession","tags":["Authentication"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Data required to create the session. Specific needs may vary based on the AuthenticationModule type in the QQQ Backend.","properties":{"accessToken":{"type":"string","description":"An access token from a downstream authentication provider (e.g., Auth0), to use as the basis for authentication and authorization."},"code":{"type":"string","description":"OAuth2 authorization code, for the backend to exchange with the identity provider (authorization-code + PKCE sign-in)."},"codeVerifier":{"type":"string","description":"PKCE code verifier that goes with `code`."},"redirectUri":{"type":"string","description":"Redirect URI the authorization `code` was issued to."},"sessionUUID":{"type":"string","description":"UUID of an existing session, to resume it instead of signing in again. Omit it (and all credentials) to resume the session named by the sessionUUID cookie."}}}}}},"parameters":[{"name":"Authorization","description":"For `TABLE_BASED` authentication: `Basic ` followed by the base64 encoding of `username:password` (UTF-8).\nNot used by other authentication types.","in":"header","schema":{"type":"string"},"example":"Basic dXNlcm5hbWU6cGFzc3dvcmQ="}],"responses":{"401":{"description":"Authentication error - session was not created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"},"examples":{"Invalid token":{"value":{"error":"Unable to decode access token.","message":"Unable to decode access token."}}}}}},"200":{"description":"Successful response - session has been created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManageSessionResponseV1"},"examples":{"With no custom values":{"value":{"uuid":"01234567-89AB-CDEF-0123-456789ABCDEF"}},"With custom values":{"value":{"uuid":"98765432-10FE-DCBA-9876-543210FEDCBA","values":{"region":"US","userCategoryId":47}}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}}}},"/qqq/v1/logout":{"post":{"summary":"Logout and invalidate session","description":"Invalidates the current session server-side, deleting it from the session store\nand clearing any cached data. The session cookie is also removed.\n\nFrontends should call this endpoint before performing client-side logout\n(clearing localStorage, redirecting to IdP logout, etc.) to ensure the\nsession cannot be resumed.","operationId":"logout","tags":["Authentication"],"responses":{"200":{"description":"Session has been invalidated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogoutResponseV1"},"examples":{"Successful logout":{}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}}}},"/qqq/v1/oidc/backchannel-logout":{"post":{"summary":"OIDC Back-Channel Logout","description":"Receives logout notifications from the Identity Provider (IdP) when a user\nlogs out from the IdP or another application in the SSO ecosystem.\n\nThe IdP sends a POST request with a 'logout_token' JWT parameter containing\neither a 'sub' (subject) or 'sid' (session ID) claim. QQQ validates the RS256\nsignature against the configured OAuth2 provider's discovered JWKS, issuer,\nclient audience, logout event and timestamps before deleting matching sessions\nfrom the configured session table. Both subject and session ID must match when\nboth are present. Invalid tokens or unsupported configuration return HTTP 400.\n\nThis endpoint should be registered with your IdP as the back-channel logout URI.","operationId":"oidcBackChannelLogout","tags":["Authentication"],"responses":{"200":{"description":"Back-channel logout processed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackChannelLogoutResponseV1"},"examples":{"Successful logout":{}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}}}},"/qqq/v1/metaData":{"get":{"summary":"Get instance metaData","description":"Load the overall metadata, as is relevant to a frontend, for the entire application, with permissions applied, as per the\nauthenticated user.\n\nThis includes:\n- Apps (both as a map of name to AppMetaData (`apps`), but also as a tree (`appTree`), for presenting\nhierarchical navigation),\n- Tables (but without all details, e.g., fields),\n- Processes (also without full details, e.g., screens),\n- Reports\n- Widgets\n- Branding\n- Help Contents\n- Environment values\n","operationId":"getMetaData","tags":["General"],"parameters":[{"name":"frontendName","description":"Name of the frontend requesting the meta-data.\nGenerally a QQQ frontend library, unless a custom application frontend has been built.","in":"query","schema":{"type":"string"},"example":"qqq-frontend-material-dashboard"},{"name":"frontendVersion","description":"Version of the frontend requesting the meta-data.","in":"query","schema":{"type":"string"},"example":"0.23.0"},{"name":"applicationName","description":"Name of the application requesting the meta-data. e.g., an instance of a specific frontend\n(i.e., an application might be deployed with 2 different qqq-frontend-material-dashboard frontends,\nin which case this attribute allows differentiation between them).","in":"query","schema":{"type":"string"},"example":"my-admin-web-app"},{"name":"applicationVersion","description":"Version of the application requesting the meta-data.","in":"query","schema":{"type":"string"},"example":"20241021"}],"responses":{"200":{"description":"Overall metadata for the application.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetaDataResponseV1"},"examples":{"Example":{"value":{"metaDataGeneration":0,"apps":{"homeApp":{"name":"homeApp","children":[{"name":"childApp","type":"APP","icon":{"name":"child_friendly"},"label":"Child App"},{"name":"person","type":"TABLE","icon":{"name":"person_outline"},"label":"Person"}],"sections":[{"name":"homeApp","tables":["person"],"icon":{"name":"badge"},"role":"PRIMARY","label":"Home App","collapsedByDefault":false}],"childMap":{"person":{"name":"person","type":"TABLE","icon":{"name":"person_outline"},"label":"Person"},"childApp":{"name":"childApp","type":"APP","icon":{"name":"child_friendly"},"label":"Child App"}},"icon":{"name":"home","semanticName":"home"},"label":"Home App"},"childApp":{"name":"childApp","children":[{"name":"samplePersonProcess","type":"PROCESS","icon":{"name":"person_add","semanticName":"person-add"},"label":"Sample Person Process"}],"sections":[{"name":"childApp","icon":{"name":"badge"},"processes":["samplePersonProcess"],"role":"PRIMARY","label":"Child App","collapsedByDefault":false}],"childMap":{"samplePersonProcess":{"name":"samplePersonProcess","type":"PROCESS","icon":{"name":"person_add","semanticName":"person-add"},"label":"Sample Person Process"}},"icon":{"name":"child_friendly"},"label":"Child App"}},"appTree":[{"name":"homeApp","type":"APP","children":[{"name":"childApp","type":"APP","children":[{"name":"samplePersonProcess","type":"PROCESS","icon":{"name":"person_add","semanticName":"person-add"},"label":"Sample Person Process"}],"icon":{"name":"child_friendly"},"label":"Child App"},{"name":"person","type":"TABLE","icon":{"name":"person_outline"},"label":"Person"}],"icon":{"name":"home","semanticName":"home"},"label":"Home App"}],"tables":{"person":{"name":"person","icon":{"name":"person_outline"},"isHidden":false,"label":"Person","metaDataGeneration":0,"capabilities":["TABLE_COUNT","TABLE_GET","TABLE_QUERY","QUERY_STATS","TABLE_INSERT","TABLE_UPDATE","TABLE_DELETE","TABLE_EXPORT"],"readPermission":true,"insertPermission":true,"editPermission":true,"deletePermission":true}},"processes":{"person.bulkInsert":{"name":"person.bulkInsert","stepFlow":"LINEAR","icon":{"name":"library_add","semanticName":"library-add"},"tableName":"person","isHidden":true,"iconName":"library_add","label":"Person Bulk Insert","hasPermission":true,"durableJobEligible":false,"durableJobAlways":false,"iconSemanticName":"library-add"},"person.bulkEdit":{"name":"person.bulkEdit","stepFlow":"LINEAR","tableName":"person","isHidden":true,"label":"Person Bulk Edit","hasPermission":true,"durableJobEligible":false,"durableJobAlways":false},"samplePersonProcess":{"name":"samplePersonProcess","stepFlow":"LINEAR","icon":{"name":"person_add","semanticName":"person-add"},"tableName":"person","isHidden":false,"iconName":"person_add","label":"Sample Person Process","hasPermission":true,"durableJobEligible":false,"durableJobAlways":false,"iconSemanticName":"person-add"},"person.bulkDelete":{"name":"person.bulkDelete","stepFlow":"LINEAR","tableName":"person","isHidden":true,"label":"Person Bulk Delete","hasPermission":true,"durableJobEligible":false,"durableJobAlways":false},"person.bulkEditWithFile":{"name":"person.bulkEditWithFile","stepFlow":"LINEAR","tableName":"person","isHidden":true,"label":"Person Bulk Edit With File","hasPermission":true,"durableJobEligible":false,"durableJobAlways":false}}}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/preferences":{"get":{"summary":"List visible sections and the signed-in user's preferences","description":"Preferences always belong to the authenticated session user. No user identifier is accepted. Unknown or hidden sections return 404; unauthenticated requests return 401. PATCH changes only supplied fields and fixed rows; invalid changes return 400 with all messages before anything is stored. Writes are audited as the user and client channel.","operationId":"listPreferenceSections","tags":["General"],"responses":{"200":{"description":"Current preferences for the session user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferencesResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/delivery/destinations":{"get":{"summary":"List authorized output destinations","operationId":"listDeliveryDestinations","tags":["General"],"responses":{"200":{"description":"Delivery response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryDestinationsResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/delivery/destinations/{name}/targets":{"post":{"summary":"Describe the next delivery target","operationId":"chooseDeliveryTargets","tags":["General"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryTargetsRequestV1"}}}},"parameters":[{"name":"name","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Delivery response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryTargetStepResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/delivery/output/{logId}":{"get":{"summary":"Download stored output as its owner or delivery administrator","operationId":"getDeliveryOutput","tags":["General"],"parameters":[{"name":"logId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Stored output; multiple attachments form a ZIP archive","content":{"application/octet-stream":{"schema":{"$ref":"#/components/schemas/DeliveryOutputResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/preferences/{sectionName}":{"get":{"summary":"Read one visible section for the signed-in user","description":"Preferences always belong to the authenticated session user. No user identifier is accepted. Unknown or hidden sections return 404; unauthenticated requests return 401. PATCH changes only supplied fields and fixed rows; invalid changes return 400 with all messages before anything is stored. Writes are audited as the user and client channel.","operationId":"getPreferenceSection","tags":["General"],"parameters":[{"name":"sectionName","description":"Registered visible preference section name, from GET /preferences.","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Current preferences for the session user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferenceSectionV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]},"patch":{"summary":"Partially update the signed-in user's preferences","description":"Preferences always belong to the authenticated session user. No user identifier is accepted. Unknown or hidden sections return 404; unauthenticated requests return 401. PATCH changes only supplied fields and fixed rows; invalid changes return 400 with all messages before anything is stored. Writes are audited as the user and client channel.","operationId":"updatePreferenceSection","tags":["General"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferenceSectionPatchRequestV1"}}}},"parameters":[{"name":"sectionName","description":"Registered visible preference section name, from GET /preferences.","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Current preferences for the session user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferenceSectionV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/preferences/{sectionName}/actions/{actionName}":{"post":{"summary":"Run an action on the signed-in user's preferences","description":"Runs a registered action for the authenticated session user. ROW actions target only rows loaded for that user and allowed by actionNames. Unknown actions or hidden sections return 404; invalid inputs return 400; unauthenticated requests return 401. Clients must confirm confirmationText before running. Secrets are shown once and must not be stored, logged, cached, or sent to analytics by clients. Responses use Cache-Control: no-store.","operationId":"runPreferenceSectionAction","tags":["General"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferenceActionRequestV1"}}}},"parameters":[{"name":"sectionName","description":"Registered visible preference section name, from GET /preferences.","required":true,"in":"path","schema":{"type":"string"}},{"name":"actionName","description":"Registered action name from the visible section.","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Current preferences for the session user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferenceActionResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/metaData/table/{tableName}":{"get":{"summary":"Get table metaData","description":"Load the full metadata for a single table, including all fields, which a frontend\nneeds to display to users.","operationId":"getTableMetaData","tags":["Tables"],"parameters":[{"name":"tableName","description":"Name of the table to load.","required":true,"in":"path","schema":{"type":"string"},"example":"person"}],"responses":{"200":{"description":"The full table metadata","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TableMetaDataResponseV1"},"examples":{"Example":{"value":{"tableMetaData":{"clientCapabilities":{"savedViews":{"available":false},"audits":{"available":false,"level":"NONE"},"bulkInsert":{"available":true,"processName":"person.bulkInsert"},"bulkEdit":{"available":true,"processName":"person.bulkEdit"},"bulkEditWithFile":{"available":true,"processName":"person.bulkEditWithFile"},"bulkDelete":{"available":true,"processName":"person.bulkDelete"}},"fields":{"id":{"name":"id","type":"INTEGER","isHeavy":false,"isRequired":false,"isEditable":true,"isHidden":false,"label":"Id","displayFormat":"%s"}},"sections":[{"name":"identity","hidden":false,"tier":"T1","icon":{"name":"badge"},"fieldNames":["id"],"label":"Identity"}],"usesVariants":false,"primaryKeyField":"id","hasRestrictedFields":false,"name":"person","icon":{"name":"person_outline"},"isHidden":false,"label":"Person","metaDataGeneration":0,"capabilities":["TABLE_COUNT","TABLE_GET","TABLE_QUERY","QUERY_STATS","TABLE_INSERT","TABLE_UPDATE","TABLE_DELETE","TABLE_EXPORT"],"readPermission":true,"insertPermission":true,"editPermission":true,"deletePermission":true}}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/query":{"post":{"summary":"Query for records from a table","description":"Execute a query against a table, returning records that match a filter.","operationId":"queryTable","tags":["Tables"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"filter":{"description":"QueryFilter to specify matching records to be returned by the query","$ref":"#/components/schemas/QueryFilter"},"joins":{"type":"array","description":"QueryJoin objects to specify tables to be joined into the query","items":{"$ref":"#/components/schemas/QueryJoin"}},"tableVariant":{"description":"For tables that use variant backends, specification of which variant to use.","$ref":"#/components/schemas/TableVariant"}}}}}},"parameters":[{"name":"tableName","description":"Name of the table to query.","required":true,"in":"path","schema":{"type":"string"},"example":"person"}],"responses":{"200":{"description":"The records matching query","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TableQueryResponseV1"},"examples":{"TODO":{"value":{"records":[{"tableName":"item","recordLabel":"Item 17","values":{"id":17,"quantity":1000,"storeId":42},"displayValues":{"id":"17","quantity":"1,000","storeId":"QQQ-Mart"}}]}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/count":{"post":{"summary":"Count records in a table","description":"Execute a query against a table, returning the number of records that match a filter.","operationId":"countTable","tags":["Tables"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"filter":{"description":"QueryFilter to specify matching records to be returned by the query","$ref":"#/components/schemas/QueryFilter"},"joins":{"type":"array","description":"QueryJoin objects to specify tables to be joined into the query","items":{"$ref":"#/components/schemas/QueryJoin"}},"tableVariant":{"description":"For tables that use variant backends, specification of which variant to use.","$ref":"#/components/schemas/TableVariant"}}}}}},"parameters":[{"name":"tableName","description":"Name of the table to count.","required":true,"in":"path","schema":{"type":"string"},"example":"person"},{"name":"includeDistinct","description":"Whether or not to also return the count distinct records from the main table (e.g., in case of a to-many join; by default, do not).","required":true,"in":"query","schema":{"type":"boolean"},"example":"true"}],"responses":{"200":{"description":"The number (count) of records matching the query","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TableCountResponseV1"},"examples":{"TODO":{"value":{"count":42}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/search":{"post":{"summary":"Search records across tables","description":"Search for records whose search fields (declared per table in its meta-data, and listed as `searchFields` in the\ntable meta-data) match a search term. String fields match when they contain the term, ignoring case; integer\nfields match when they equal a numeric term. Only tables that the user has permission to read are searched,\nrecord security locks apply, and each table returns at most `limitPerTable` records (default 5, maximum 25), after skipping `offset` matches in each table (for paging one table). An instance may have a record search\nprovider (e.g., a search index) that searches some tables instead; if it fails, those tables are searched with\nthe default search, and the response's `provider` and `tables` say so.\n\nEach result can carry plain-text `highlights` of the fields that match (with the matched spans as character\noffsets - never markup), `details` (other search field values), `updatedAt` and, from a provider, a `score`.\nOnly fields the user may see are used. All of these, and `tables` and `provider`, are optional: clients must\ntolerate their absence.","operationId":"searchRecords","tags":["Tables"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"searchTerm":{"type":"string","description":"Text to search for (required; at most 100 characters after trimming).","example":"Kelkhoff"},"tableNames":{"type":"array","description":"Optional list of table names to search. When omitted or empty, every table with search fields is searched.","items":{"type":"string"}},"limitPerTable":{"type":"number","description":"Maximum number of records to return from each table."},"offset":{"type":"number","description":"Number of matches to skip in each table, for paging (default 0, maximum 1000). Mainly useful with one table in tableNames."},"sort":{"type":"string","description":"Order of the results within each table: RELEVANCE (default) or RECENT (most recently modified first, for tables with a last-modified field).","enum":["RELEVANCE","RECENT"]}}}}}},"responses":{"200":{"description":"The records matching the search term","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSearchResponseV1"},"examples":{"Matches in one table":{"value":{"results":[{"recordId":"1","tableLabel":"Person","score":7.25,"updatedAt":"2026-10-01T14:30:00Z","highlights":[{"text":"darin.kelkhoff@example.com","fieldName":"email","fieldLabel":"Email","matches":[{"start":6,"end":14}]}],"details":[{"fieldName":"city","fieldLabel":"City","displayValue":"Saint Louis"}],"tableName":"person","recordLabel":"Darin Kelkhoff"},{"recordId":"2","tableLabel":"Person","score":6.5,"tableName":"person","recordLabel":"Tim Kelkhoff"}],"tables":[{"source":"PROVIDER","tableLabel":"Person","resultCount":2,"hasMore":true,"tableName":"person","totalCount":14}],"provider":{"status":"OK"}}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/help/search":{"get":{"summary":"Search visible application help","description":"Search help visible to the session. Label hits weigh 3, summary hits 2 and content hits 1. Stable ties sort by kind and key. Limit defaults to 20 and is capped at 50.","operationId":"searchHelp","tags":["General"],"parameters":[{"name":"q","required":true,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"Help search results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HelpSearchResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/help/coverage":{"get":{"summary":"Inspect application help coverage","description":"Requires INSERT or EDIT permission on helpContent. Includes hidden targets. Totals reflect kind and parent scope before missingOnly is applied.","operationId":"getHelpCoverage","tags":["General"],"parameters":[{"name":"kind","required":false,"in":"query","schema":{"type":"string"}},{"name":"missingOnly","required":false,"in":"query","schema":{"type":"boolean"}},{"name":"parentKey","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"403":{"description":"No INSERT or EDIT permission on helpContent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"200":{"description":"Help coverage results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HelpCoverageResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/variants":{"get":{"summary":"List a table's backend variants","description":"List the variants a table's backend can be scoped to (for example one data set per store). Requires read\npermission on the table and on the backend's variant options table.","operationId":"listTableVariants","tags":["Tables"],"parameters":[{"name":"tableName","description":"Name of the table whose variants to list.","required":true,"in":"path","schema":{"type":"string"},"example":"person"}],"responses":{"200":{"description":"The variants the table can be scoped to.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TableVariantsResponseV1"},"examples":{"A table with variants":{"value":{"variants":[{"type":"store","id":"1","name":"Main Street"}]}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/apis":{"get":{"summary":"List the APIs that expose a table","description":"The application APIs (served by the API middleware beside this one) that expose the table, with each API's versions and the root-relative path of the table's OpenAPI document in each version. Empty when the application serves no APIs. The caller must be allowed to read the table.","operationId":"listTableApis","tags":["Tables"],"parameters":[{"name":"tableName","description":"Name of the table.","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TableApisResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/{primaryKey}":{"get":{"summary":"Get a record from a table by primary key","description":"Fetch a single record from a table, identified by its primary key value.","operationId":"getRecord","tags":["Tables"],"parameters":[{"name":"tableName","description":"Name of the table to get the record from.","required":true,"in":"path","schema":{"type":"string"},"example":"person"},{"name":"primaryKey","description":"Primary key value of the record to get.","required":true,"in":"path","schema":{"type":"string"},"example":"42"},{"name":"includeAssociations","description":"Whether or not to include associated records.","required":false,"in":"query","schema":{"type":"boolean"},"example":"true"},{"name":"queryJoins","description":"JSON array of QueryJoin objects specifying tables to join into the get.","required":false,"in":"query","schema":{"type":"string"},"example":"[{\"joinTable\":\"orderLine\",\"select\":true}]"},{"name":"tableVariant","description":"For tables that use variant backends, JSON object naming the variant to read from (the same `type` and `id` as in query requests).","required":false,"in":"query","schema":{"type":"string"},"example":"{\"type\":\"store\",\"id\":\"1\"}"}],"responses":{"200":{"description":"The record matching the given primary key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TableGetResponseV1"},"examples":{"TODO":{"value":{"record":{"tableName":"person","recordLabel":"Darin Kelkhoff","values":{"id":1,"firstName":"Darin","lastName":"Kelkhoff"},"displayValues":{"id":"1","firstName":"Darin","lastName":"Kelkhoff"}}}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]},"patch":{"summary":"Update a record in a table","description":"Update an existing record in a table, identified by its primary key. The request body should contain the field values to update.","operationId":"updateRecord","tags":["Tables"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","description":"JSON object with field names as keys and field values as values.","properties":{"fieldName":{"type":"string","description":"Value for a field in the record. Repeat for each field to update."}}}},"multipart/form-data":{"schema":{"type":"object","description":"Form fields named for the record's fields (an empty field clears the value), a file for each blob field to set, and optionally an `associations` field: JSON of association name to a list of associated records. With the request header `X-QQQ-Association-Format: record-v1`, each associated record is `{\"values\": {...}, \"associations\": {...}}`, nested to any depth, and exactly one `associations` field is required.","properties":{"fieldName":{"type":"string","description":"Value for a field in the record. Repeat for each field to set."},"associations":{"type":"string","description":"JSON object of association name to a list of associated records."}}}}}},"parameters":[{"name":"expectedVersion","description":"Optional optimistic version from the last read, encoded as a string in the version field's format (ISO-8601 for modify dates). A mismatch returns 409 RecordConflictV1 and leaves the record unchanged. Omit for an unconditional update. Tables with recordVersionField set to an empty string opt out.","required":false,"in":"query","schema":{"type":"string"}},{"name":"tableName","description":"Name of the table containing the record to update.","required":true,"in":"path","schema":{"type":"string"},"example":"person"},{"name":"primaryKey","description":"Primary key value of the record to update.","required":true,"in":"path","schema":{"type":"string"},"example":"42"}],"responses":{"200":{"description":"The record that was updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TableUpdateResponseV1"},"examples":{"TODO":{"value":{"record":{"tableName":"person","recordLabel":"Darin Kelkhoff","values":{"id":1,"firstName":"Darin","lastName":"Kelkhoff"},"displayValues":{"id":"1","firstName":"Darin","lastName":"Kelkhoff"}}}}}}}},"409":{"description":"The record changed since it was read.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordConflictV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]},"delete":{"summary":"Delete a record from a table","description":"Delete a single record from a table, identified by its primary key value.","operationId":"deleteRecord","tags":["Tables"],"parameters":[{"name":"tableName","description":"Name of the table to delete from.","required":true,"in":"path","schema":{"type":"string"},"example":"person"},{"name":"primaryKey","description":"Primary key value of the record to delete.","required":true,"in":"path","schema":{"type":"string"},"example":"42"}],"responses":{"200":{"description":"The number of records that were deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TableDeleteResponseV1"},"examples":{"TODO":{"value":{"deletedRecordCount":1}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/{primaryKey}/features":{"get":{"summary":"Get record collaboration features","description":"Features and capabilities for a visible record, with optional summary provider contributions.","operationId":"getRecordFeatures","tags":["Tables"],"parameters":[{"name":"tableName","required":true,"in":"path","schema":{"type":"string"}},{"name":"primaryKey","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Record collaboration summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordFeatureSummaryV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/formAdjuster/{identifier}/{event}":{"post":{"summary":"Run a form adjuster","description":"Run one of a table form's adjusters and return the changes to apply to the form. The identifier is `table:{tableName}` for the table's on-load adjuster, or a field's `formAdjusterIdentifier` (from its `materialDashboard` supplemental metadata) for that field's adjusters. The caller must be allowed to insert or edit records in the table. Answers 404 when the application registers no form adjusters.","operationId":"runFormAdjuster","tags":["Tables"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"The form's state when the event fired.","properties":{"fieldName":{"type":"string","description":"The field the event is for (field adjusters)."},"newValue":{"description":"The field's new value (field adjusters); sent to the adjuster as text."},"allValues":{"type":"object","description":"Every value of the form, by field name.","additionalProperties":true}}}}}},"parameters":[{"name":"tableName","description":"Name of the table whose form is being adjusted.","required":true,"in":"path","schema":{"type":"string"}},{"name":"identifier","description":"`table:{tableName}`, or a field's `formAdjusterIdentifier`.","required":true,"in":"path","schema":{"type":"string"}},{"name":"event","description":"Which adjuster to run.","required":true,"in":"path","schema":{"type":"string","enum":["onLoad","onChange"]}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormAdjusterOutputV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/apis/{apiName}/{version}/openapi":{"get":{"summary":"Get a table's OpenAPI document in an application API","description":"The OpenAPI 3 document of the table in one version of an application API that exposes it (as listed by `GET /table/{tableName}/apis`). The caller must be allowed to read the table. Answers 404 when no API by that name exposes the table in that version.","operationId":"getTableApiDocument","tags":["Tables"],"parameters":[{"name":"tableName","description":"Name of the table.","required":true,"in":"path","schema":{"type":"string"}},{"name":"apiName","description":"The API's name (`name` in `GET /table/{tableName}/apis`).","required":true,"in":"path","schema":{"type":"string"}},{"name":"version","description":"The API version (`versions[].version`).","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TableApiDocumentV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}":{"post":{"summary":"Insert a record into a table","description":"Insert a new record into a table. The request body should contain the field values for the new record.","operationId":"insertRecord","tags":["Tables"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","description":"JSON object with field names as keys and field values as values.","properties":{"fieldName":{"type":"string","description":"Value for a field in the record. Repeat for each field to set."}}}},"multipart/form-data":{"schema":{"type":"object","description":"Form fields named for the record's fields (an empty field clears the value), a file for each blob field to set, and optionally an `associations` field: JSON of association name to a list of associated records. With the request header `X-QQQ-Association-Format: record-v1`, each associated record is `{\"values\": {...}, \"associations\": {...}}`, nested to any depth, and exactly one `associations` field is required.","properties":{"fieldName":{"type":"string","description":"Value for a field in the record. Repeat for each field to set."},"associations":{"type":"string","description":"JSON object of association name to a list of associated records."}}}}}},"parameters":[{"name":"tableName","description":"Name of the table to insert into.","required":true,"in":"path","schema":{"type":"string"},"example":"person"}],"responses":{"200":{"description":"The record that was inserted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TableInsertResponseV1"},"examples":{"TODO":{"value":{"record":{"tableName":"person","recordLabel":"New Person","values":{"id":47,"firstName":"New","lastName":"Person"},"displayValues":{"id":"47","firstName":"New","lastName":"Person"}}}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/relatedRecordPicker/{pickerName}/query":{"post":{"summary":"Query the records a related-record picker offers","description":"Lists one page of the picker's target records as the user may read them: the user's filter (the target table's own filter builder or a saved view), ANDed with the picker's filter (resolved from the parent record or form values) and the search term. Needs READ on the target table; table permissions, record security locks and field security locks apply as on the table query route. Reads limit + 1 rows for hasMore (no count). For MULTI_CHILD and LINK with a primaryKey, linkedIds says which returned records the parent already has rows for.","operationId":"queryRelatedRecordPicker","tags":["Tables"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"primaryKey":{"type":"string","description":"Primary key of the parent record (required for MULTI_CHILD and LINK; for SINGLE, the record being edited, if any). Read with the user's own security."},"values":{"type":"object","description":"Current form values (SINGLE on a create form, when there is no primaryKey), for ${input.fieldName} variables in the picker's filters"},"searchTerm":{"type":"string","description":"Case-insensitive text matched (contains) against the target table's search fields, or its record-label fields"},"filter":{"description":"The user's filter on the target table (criteria and orderBys on target fields only); ANDed with the picker's filter","$ref":"#/components/schemas/QueryFilter"},"skip":{"type":"integer","description":"Records to skip (offset paging)"},"limit":{"type":"integer","description":"Records per page, 1 to 200 (default 50)"}}}}}},"parameters":[{"name":"tableName","description":"Name of the table that declares the picker (e.g. the order).","required":true,"in":"path","schema":{"type":"string"},"example":"sales_order"},{"name":"pickerName","description":"Name of the picker, from the table metadata's relatedRecordPickers.","required":true,"in":"path","schema":{"type":"string"},"example":"addSkus"}],"responses":{"200":{"description":"Query the records a related-record picker offers: result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelatedRecordPickerQueryResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/relatedRecordPicker/{pickerName}/prepare":{"post":{"summary":"Prepare child rows for picked records (MULTI_CHILD, LINK)","description":"Builds, without saving, one child row per picked target: the picker's child field defaults, values copied from the target, and the parent and target keys. The client shows the reviewFieldNames of each row for the user to fill, then calls add. Needs INSERT on the child table; every target must be available through the picker's query (else 400).","operationId":"prepareRelatedRecordPicker","tags":["Tables"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"primaryKey":{"type":"string","description":"Primary key of the parent record. Read with the user's own security."},"targetIds":{"type":"array","description":"Primary keys of the picked target records","items":{"type":"string"}}}}}}},"parameters":[{"name":"tableName","description":"Name of the table that declares the picker (e.g. the order).","required":true,"in":"path","schema":{"type":"string"},"example":"sales_order"},{"name":"pickerName","description":"Name of the picker, from the table metadata's relatedRecordPickers.","required":true,"in":"path","schema":{"type":"string"},"example":"addSkus"}],"responses":{"200":{"description":"Prepare child rows for picked records (MULTI_CHILD, LINK): result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelatedRecordPickerPrepareResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/relatedRecordPicker/{pickerName}/add":{"post":{"summary":"Add child or join rows for picked records (MULTI_CHILD, LINK)","description":"Inserts one row per picked target (targetIds) or per reviewed row (records), all or nothing, through the standard insert action: INSERT permission on the child table, record security locks, validation, customizers, automations and audit. Only the picker's review fields are taken from the client; the parent and target keys always come from the server. Every target must be available through the picker's query (else 400). Row errors are a 400 naming each row, and nothing is saved.","operationId":"addRelatedRecords","tags":["Tables"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"primaryKey":{"type":"string","description":"Primary key of the parent record. Read with the user's own security."},"targetIds":{"type":"array","description":"Primary keys of the picked target records","items":{"type":"string"}},"records":{"type":"array","description":"Reviewed child rows (instead of targetIds), e.g. the prepare route's rows after the user filled the review fields","items":{"type":"object","properties":{"values":{"type":"object","description":"The row's values: the childTargetFieldName (which target) and the picker's reviewFieldNames; other values are ignored, and the parent and target keys always come from the server"}}}}}}}}},"parameters":[{"name":"tableName","description":"Name of the table that declares the picker (e.g. the order).","required":true,"in":"path","schema":{"type":"string"},"example":"sales_order"},{"name":"pickerName","description":"Name of the picker, from the table metadata's relatedRecordPickers.","required":true,"in":"path","schema":{"type":"string"},"example":"addSkus"}],"responses":{"200":{"description":"Add child or join rows for picked records (MULTI_CHILD, LINK): result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelatedRecordPickerAddResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/relatedRecordPicker/{pickerName}/remove":{"post":{"summary":"Unlink picked records (LINK)","description":"Deletes the parent's join rows for the given targets through the standard delete action (DELETE permission on the join table, record security locks, audit). Only for LINK pickers (else 400); child rows of a MULTI_CHILD picker are deleted with the table delete route.","operationId":"removeRelatedRecords","tags":["Tables"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"primaryKey":{"type":"string","description":"Primary key of the parent record. Read with the user's own security."},"targetIds":{"type":"array","description":"Primary keys of the picked target records","items":{"type":"string"}}}}}}},"parameters":[{"name":"tableName","description":"Name of the table that declares the picker (e.g. the order).","required":true,"in":"path","schema":{"type":"string"},"example":"sales_order"},{"name":"pickerName","description":"Name of the picker, from the table metadata's relatedRecordPickers.","required":true,"in":"path","schema":{"type":"string"},"example":"addSkus"}],"responses":{"200":{"description":"Unlink picked records (LINK): result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelatedRecordPickerRemoveResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/{primaryKey}/developer":{"get":{"summary":"Get a record's associated scripts (developer mode)","description":"Fetch a single record (with display values), along with each of its table's associated scripts:\nthe script type, the script that the record references (if any) with its revisions (newest first),\nand, for scripts that can be tested, the fields to test them with.\n\nRequires permission to read records from the table. If the record is not found, a 404 is returned.","operationId":"getRecordDeveloperMode","tags":["Tables"],"parameters":[{"name":"tableName","description":"Name of the table that the record is in.","required":true,"in":"path","schema":{"type":"string"},"example":"person"},{"name":"primaryKey","description":"Primary key value of the record.","required":true,"in":"path","schema":{"type":"string"},"example":"42"}],"responses":{"200":{"description":"The record, with its table's associated scripts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeveloperModeResponseV1"},"examples":{"TODO":{"value":{"record":{"tableName":"person","recordLabel":"Darin Kelkhoff","values":{"id":1,"firstName":"Darin","greetingScriptId":7},"displayValues":{"id":"1","firstName":"Darin","greetingScriptId":"7"}},"associatedScripts":[{"script":{"tableName":"script","recordLabel":"Darin Kelkhoff - Greeting","values":{"id":7,"name":"Darin Kelkhoff - Greeting","scriptTypeId":1,"currentScriptRevisionId":12}},"scriptType":{"tableName":"scriptType","recordLabel":"Greeting","values":{"id":1,"name":"Greeting"}},"associatedScript":{"fieldName":"greetingScriptId","scriptTypeId":1},"scriptRevisions":[{"tableName":"scriptRevision","values":{"id":12,"scriptId":7,"sequenceNo":2,"commitMessage":"Say hello by name"}}],"testInputFields":[{"name":"name","type":"STRING","isHeavy":false,"isRequired":false,"isEditable":true,"isHidden":false,"label":"Name","displayFormat":"%s"}],"testOutputFields":[{"name":"message","type":"STRING","isHeavy":false,"isRequired":false,"isEditable":true,"isHidden":false,"label":"Message","displayFormat":"%s"}]}]}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/{primaryKey}/developer/panels":{"get":{"summary":"Get a record's developer panels","description":"Fetch the panels shown on a record's developer view: one per developer panel provider (built in, or\nregistered by modules and qbits in the instance's developerPanels supplemental meta-data) that is available\nfor this table and record for the current user - for example record security, ESB events, quick search\nindexing, or SQL workbench queries.\n\nRequires permission to read records from the table, and the record must be visible under its record\nsecurity locks. If the record is not found, a 404 is returned. A provider that fails yields a panel\nwith an error message rather than failing the request.","operationId":"listRecordDeveloperPanels","tags":["Tables"],"parameters":[{"name":"tableName","description":"Name of the table that the record is in.","required":true,"in":"path","schema":{"type":"string"},"example":"person"},{"name":"primaryKey","description":"Primary key value of the record.","required":true,"in":"path","schema":{"type":"string"},"example":"42"}],"responses":{"200":{"description":"The record's developer panels","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeveloperPanelsResponseV1"},"examples":{"Record security":{"value":{"panels":[{"id":"recordSecurity","title":"Record Security","order":150,"statusLabel":"1 lock","statusTone":"SUCCESS","blocks":[{"type":"TABLE","label":"Locks","columns":["Security key","Field","Scope","Null values","This record's value","Your access"],"rows":[["store","storeId","READ_AND_WRITE","DENY","42","Your session has key value 42"]]}]}]}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/{primaryKey}/developer/associatedScript/{fieldName}":{"post":{"summary":"Store a new revision of a record's associated script (developer mode)","description":"Save new contents for the script that a record references in one of its table's associated script\nfields, as a new revision of that script. If the record does not yet reference a script, one is\ninserted (and the record is updated to reference it).\n\nRequires permission to edit records in the table.","operationId":"storeAssociatedScript","tags":["Tables"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"contents":{"type":"string","description":"The script's new contents (its code).","example":"return (\"Hello, \" + input.getName());"},"commitMessage":{"type":"string","description":"A message describing the change. If not given, a default message is used.","example":"Say hello by name"}}}}}},"parameters":[{"name":"tableName","description":"Name of the table that the record is in.","required":true,"in":"path","schema":{"type":"string"},"example":"person"},{"name":"primaryKey","description":"Primary key value of the record.","required":true,"in":"path","schema":{"type":"string"},"example":"42"},{"name":"fieldName","description":"Name of the associated script field (in the table) whose script is being stored.","required":true,"in":"path","schema":{"type":"string"},"example":"greetingScriptId"}],"responses":{"200":{"description":"The script, and the revision that was stored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordAssociatedScriptStoreResponseV1"},"examples":{"TODO":{"value":{"scriptId":7,"scriptName":"Darin Kelkhoff - Greeting","scriptRevisionId":13,"scriptRevisionSequenceNo":3}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/{primaryKey}/developer/associatedScript/{fieldName}/{scriptRevisionId}/logs":{"get":{"summary":"Get the logs of a record's associated script revision (developer mode)","description":"Fetch the logs (up to 100, newest first) of runs of a script revision, each with its log lines.\n\nRequires permission to read records from the table, and the record must exist (else a 404 is returned).","operationId":"getAssociatedScriptLogs","tags":["Tables"],"parameters":[{"name":"tableName","description":"Name of the table that the record is in.","required":true,"in":"path","schema":{"type":"string"},"example":"person"},{"name":"primaryKey","description":"Primary key value of the record.","required":true,"in":"path","schema":{"type":"string"},"example":"42"},{"name":"fieldName","description":"Name of the associated script field (in the table) whose script the revision is of.","required":true,"in":"path","schema":{"type":"string"},"example":"greetingScriptId"},{"name":"scriptRevisionId","description":"Id of the script revision to get logs for.","required":true,"in":"path","schema":{"type":"string"},"example":"12"}],"responses":{"200":{"description":"The script revision's logs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordAssociatedScriptLogsResponseV1"},"examples":{"TODO":{"value":{"scriptLogRecords":[{"tableName":"scriptLog","values":{"id":101,"scriptRevisionId":12,"startTimestamp":"2024-10-21T14:30:00Z","hadError":false,"scriptLogLine":[{"tableName":"scriptLogLine","values":{"id":1001,"scriptLogId":101,"timestamp":"2024-10-21T14:30:00Z","text":"Hello, Darin"}}]}}]}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/possibleValues/{fieldName}":{"post":{"summary":"Search possible values for a table field","description":"Search for possible values associated with a field on a table.\nReturns a list of id/label pairs that match the given search criteria.","operationId":"searchTablePossibleValues","tags":["Tables"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"searchTerm":{"type":"string","description":"Text to search for within possible value labels"},"ids":{"type":"array","description":"List of specific ids to look up","items":{"type":"string"}},"values":{"type":"object","description":"Map of other field values, used for filter interpolation on possible value source filters"},"useCase":{"type":"string","description":"Use case for possible value search filtering. Controls behavior when filter values are missing.","enum":["FORM","FILTER"]},"labels":{"type":"array","description":"List of specific labels to look up","items":{"type":"string"}},"processValues":{"type":"object","description":"Map of field values from the current process step, used for filter interpolation"},"filter":{"description":"Optional default filter to apply to the possible value search","$ref":"#/components/schemas/QueryFilter"},"picker":{"type":"object","description":"Record picker request, for a possible value source that declares a picker: options carry the picker's display values and the response says whether more follow (no count)","properties":{"filter":{"description":"Criteria (only on the picker's filterFields) and orderBys (only on its sort fields or the primary key)","$ref":"#/components/schemas/QueryFilter"},"afterId":{"type":"string","description":"Keyset paging: the last option id of the previous page, when ordered by the primary key alone"},"skip":{"type":"integer","description":"Offset paging, for orderings other than the primary key"},"limit":{"type":"integer","description":"Options per page (default: the picker's pageSize; at most 200)"}}}}}}}},"parameters":[{"name":"tableName","description":"Name of the table containing the field.","required":true,"in":"path","schema":{"type":"string"},"example":"person"},{"name":"fieldName","description":"Name of the field whose possible values should be searched.","required":true,"in":"path","schema":{"type":"string"},"example":"partnerPersonId"}],"responses":{"200":{"description":"List of possible value options matching the search criteria.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PossibleValuesResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/processes/{processName}/possibleValues/{fieldName}":{"post":{"summary":"Search possible values for a process field","description":"Search for possible values associated with an input field on a process.\nReturns a list of id/label pairs that match the given search criteria.","operationId":"searchProcessPossibleValues","tags":["Processes"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"searchTerm":{"type":"string","description":"Text to search for within possible value labels"},"ids":{"type":"array","description":"List of specific ids to look up","items":{"type":"string"}},"values":{"type":"object","description":"Map of other field values, used for filter interpolation on possible value source filters"},"useCase":{"type":"string","description":"Use case for possible value search filtering. Controls behavior when filter values are missing.","enum":["FORM","FILTER"]},"labels":{"type":"array","description":"List of specific labels to look up","items":{"type":"string"}},"processValues":{"type":"object","description":"Map of field values from the current process step, used for filter interpolation"},"filter":{"description":"Optional default filter to apply to the possible value search","$ref":"#/components/schemas/QueryFilter"},"picker":{"type":"object","description":"Record picker request, for a possible value source that declares a picker: options carry the picker's display values and the response says whether more follow (no count)","properties":{"filter":{"description":"Criteria (only on the picker's filterFields) and orderBys (only on its sort fields or the primary key)","$ref":"#/components/schemas/QueryFilter"},"afterId":{"type":"string","description":"Keyset paging: the last option id of the previous page, when ordered by the primary key alone"},"skip":{"type":"integer","description":"Offset paging, for orderings other than the primary key"},"limit":{"type":"integer","description":"Options per page (default: the picker's pageSize; at most 200)"}}}}}}}},"parameters":[{"name":"processName","description":"Name of the process containing the field.","required":true,"in":"path","schema":{"type":"string"},"example":"greetInteractive"},{"name":"fieldName","description":"Name of the field whose possible values should be searched.","required":true,"in":"path","schema":{"type":"string"},"example":"partnerPersonId"}],"responses":{"200":{"description":"List of possible value options matching the search criteria.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PossibleValuesResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/possibleValues/{possibleValueSourceName}":{"post":{"summary":"Search a standalone possible value source","description":"Search for possible values from a standalone possible value source\n(not associated with a specific table or process field).\nReturns a list of id/label pairs that match the given search criteria.","operationId":"searchPossibleValues","tags":["General"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"searchTerm":{"type":"string","description":"Text to search for within possible value labels"},"ids":{"type":"array","description":"List of specific ids to look up","items":{"type":"string"}},"values":{"type":"object","description":"Map of other field values, used for filter interpolation on possible value source filters"},"useCase":{"type":"string","description":"Use case for possible value search filtering. Controls behavior when filter values are missing.","enum":["FORM","FILTER"]},"labels":{"type":"array","description":"List of specific labels to look up","items":{"type":"string"}},"processValues":{"type":"object","description":"Map of field values from the current process step, used for filter interpolation"},"filter":{"description":"Optional default filter to apply to the possible value search","$ref":"#/components/schemas/QueryFilter"},"picker":{"type":"object","description":"Record picker request, for a possible value source that declares a picker: options carry the picker's display values and the response says whether more follow (no count)","properties":{"filter":{"description":"Criteria (only on the picker's filterFields) and orderBys (only on its sort fields or the primary key)","$ref":"#/components/schemas/QueryFilter"},"afterId":{"type":"string","description":"Keyset paging: the last option id of the previous page, when ordered by the primary key alone"},"skip":{"type":"integer","description":"Offset paging, for orderings other than the primary key"},"limit":{"type":"integer","description":"Options per page (default: the picker's pageSize; at most 200)"}}}}}}}},"parameters":[{"name":"possibleValueSourceName","description":"Name of the possible value source to search.","required":true,"in":"path","schema":{"type":"string"},"example":"person"}],"responses":{"200":{"description":"List of possible value options matching the search criteria.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PossibleValuesResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/widget/{widgetName}":{"post":{"summary":"Render a widget","description":"Render a widget by name, passing in query parameters as a JSON object in the request body.\nThe response shape varies by widget type.","operationId":"getWidgetData","tags":["Widgets"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","description":"Dynamic inputs to pass to the widget renderer (e.g. the record id, dropdown selections). The same inputs may instead be sent as query parameters; a body value wins over a query parameter of the same name.","additionalProperties":{"type":"string"}}}}},"parameters":[{"name":"widgetName","description":"Name of the widget to render.","required":true,"in":"path","schema":{"type":"string"},"example":"myWidget"}],"responses":{"200":{"description":"The rendered widget data itself (not wrapped): one of the WidgetData shapes, chosen by its `type`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WidgetData"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/metaData/process/{processName}":{"get":{"summary":"Get process metaData","description":"Load the full metadata for a single process, including all screens (aka, frontend steps), which a frontend\nneeds to display to users.","operationId":"getProcessMetaData","tags":["Processes"],"parameters":[{"name":"processName","description":"Name of the process to load.","required":true,"in":"path","schema":{"type":"string"},"example":"samplePersonProcess"}],"responses":{"200":{"description":"The full process metadata","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProcessMetaDataResponseV1"},"examples":{"TODO":{"value":{}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/processes/{processName}/init":{"post":{"summary":"Initialize a process","description":"For a user to start running a process, this endpoint should be called, to start the process\nand run its first step(s) (any backend steps before the first frontend step).\n\nAdditional process-specific values should posted in a form param named `values`, as JSON object\nwith keys defined by the process in question.\n\nFor a process which needs to operate on a set of records that a user selected, see\n`recordsParam`, and `recordIds` or `filterJSON`.\n\nThe response will include a `processUUID`, to be included in all subsequent requests relevant\nto the process.\n\nNote that this request, if it takes longer than a given threshold* to complete, will return a\na `jobUUID`, which should be sent to the `/processes/{processName}/{processUUID}/status/{jobUUID}`\nendpoint, to poll for a status update.\n\n*This threshold has a default value of 3,000 ms., but can be set per-request via the form\nparameter `stepTimeoutMillis`.\n","operationId":"initProcess","tags":["Processes"],"requestBody":{"required":false,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"values":{"type":"object","description":"Process-specific field names and values."},"recordsParam":{"type":"string","description":"Specifies which other query-param will contain the indicator of initial records to pass in to the process.","examples":{"recordIds":{"value":"recordIds"},"filterJSON":{"value":"recordIds"}}},"recordIds":{"type":"string","description":"Comma-separated list of ids from the table this process is based on, to use as input records for the process. Needs `recordsParam=recordIds` value to be given as well.","examples":{"one id":{"value":"1701"},"multiple ids":{"value":"42,47"}}},"filterJSON":{"type":"string","description":"JSON encoded QQueryFilter object, to execute against the table this process is based on, to find input records for the process. Needs `recordsParam=filterJSON` value to be given as well.","examples":{"empty filter (all records)":{"value":"{}"},"filter by a condition":{"value":"{\"criteria\":[{\"fieldName\":\"id\",\"operator\":\"LESS_THAN\",\"values\":[10]}],\"booleanOperator\":\"AND\"}"}}},"stepTimeoutMillis":{"type":"integer","description":"Optionally change the time that the server will wait for the job before letting it go asynchronous. Default value is 3000.","examples":{"shorter timeout":{"value":"500"},"longer timeout":{"value":"60000"}}},"file":{"type":"string","format":"binary","description":"A file upload, for processes which expect to be initialized with an uploaded file."},"tableVariant":{"type":"string","description":"For processes on tables that use variant backends, JSON object naming the variant to use (the same `type` and `id` as in table requests). May also be given as a query parameter.","example":"{\"type\":\"store\",\"id\":\"1\"}"}}}}}},"parameters":[{"name":"processName","description":"Name of the process to initialize","required":true,"in":"path","schema":{"type":"string"},"example":"samplePersonProcess"},{"name":"tableVariant","description":"For processes on tables that use variant backends, JSON object naming the variant to use (the same `type` and `id` as in table requests).","required":false,"in":"query","schema":{"type":"string"},"example":"{\"type\":\"store\",\"id\":\"1\"}"}],"responses":{"200":{"description":"State of the initialization of the job, with different fields set, based on the\nstatus of the task.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProcessStepResponseV1"},"examples":{"COMPLETE":{"value":{"values":{"firstLastName":"Aabramson","totalAge":32768},"processUUID":"01234567-89AB-CDEF-0123-456789ABCDEF","nextStep":"reviewScreen","type":"COMPLETE"}},"COMPLETE with metaDataAdjustment":{"value":{"values":{"firstLastName":"Aabramson","totalAge":32768},"processUUID":"01234567-89AB-CDEF-0123-456789ABCDEF","nextStep":"inputScreen","processMetaDataAdjustment":{"updatedFields":{"someField":{"isRequired":true,"isEditable":true,"name":"someField","displayFormat":"%s","type":"STRING","isHeavy":false,"validation":{"required":true},"isHidden":false}},"updatedFrontendStepList":[{"components":[{"type":"EDIT_FORM"}],"name":"inputScreen","formFields":[{"isRequired":false,"isEditable":true,"name":"someField","displayFormat":"%s","type":"STRING","isHeavy":false,"isHidden":false}]},{"components":[{"type":"PROCESS_SUMMARY_RESULTS"}],"name":"resultScreen"}]},"type":"COMPLETE"}},"JOB_STARTED":{"value":{"jobUUID":"98765432-10FE-DCBA-9876-543210FEDCBA","processUUID":"01234567-89AB-CDEF-0123-456789ABCDEF","type":"JOB_STARTED"}},"RUNNING":{"value":{"current":47,"total":1701,"processUUID":"01234567-89AB-CDEF-0123-456789ABCDEF","type":"RUNNING","message":"Processing person records"}},"ERROR":{"value":{"processUUID":"01234567-89AB-CDEF-0123-456789ABCDEF","type":"RUNNING"}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/processes/{processName}/{processUUID}/step/{stepName}":{"post":{"summary":"Run a step in a process","description":"To run the next step in a process, this endpoint should be called, with the `processName`\nand existing `processUUID`, as well as the step that was just completed in the frontend,\ngiven as `stepName`.\n\nAdditional process-specific values should posted in a form param named `values`, as JSON object\nwith keys defined by the process in question.\n\nNote that this request, if it takes longer than a given threshold* to complete, will return a\na `jobUUID`, which should be sent to the `/processes/{processName}/{processUUID}/status/{jobUUID}`\nendpoint, to poll for a status update.\n\n*This threshold has a default value of 3,000 ms., but can be set per-request via the form\nparameter `stepTimeoutMillis`.\n","operationId":"stepProcess","tags":["Processes"],"requestBody":{"required":false,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"values":{"type":"object","description":"Process-specific field names and values."},"stepTimeoutMillis":{"type":"integer","description":"Optionally change the time that the server will wait for the job before letting it go asynchronous. Default value is 3000.","examples":{"shorter timeout":{"value":"500"},"longer timeout":{"value":"60000"}}},"file":{"type":"string","format":"binary","description":"A file upload, for process steps which expect an uploaded file."},"tableVariant":{"type":"string","description":"For processes on tables that use variant backends, JSON object naming the variant to use (the same `type` and `id` as in table requests). May also be given as a query parameter.","example":"{\"type\":\"store\",\"id\":\"1\"}"}}}}}},"parameters":[{"name":"processName","description":"Name of the process to perform the step in.","required":true,"in":"path","schema":{"type":"string"},"example":"samplePersonProcess"},{"name":"processUUID","description":"Unique identifier for this run of the process - as was returned by the `init` call.","required":true,"in":"path","schema":{"type":"string"},"example":"01234567-89AB-CDEF-0123-456789ABCDEF"},{"name":"stepName","description":"Name of the frontend step that the user has just completed.","required":true,"in":"path","schema":{"type":"string"},"example":"inputForm"},{"name":"tableVariant","description":"For processes on tables that use variant backends, JSON object naming the variant to use (the same `type` and `id` as in table requests).","required":false,"in":"query","schema":{"type":"string"},"example":"{\"type\":\"store\",\"id\":\"1\"}"}],"responses":{"200":{"description":"State of the backend's running of the next step(s) of the job, with different fields set,\nbased on the status of the job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProcessStepResponseV1"},"examples":{"COMPLETE":{"value":{"values":{"firstLastName":"Aabramson","totalAge":32768},"processUUID":"01234567-89AB-CDEF-0123-456789ABCDEF","nextStep":"reviewScreen","type":"COMPLETE"}},"COMPLETE with metaDataAdjustment":{"value":{"values":{"firstLastName":"Aabramson","totalAge":32768},"processUUID":"01234567-89AB-CDEF-0123-456789ABCDEF","nextStep":"inputScreen","processMetaDataAdjustment":{"updatedFields":{"someField":{"isRequired":true,"isEditable":true,"name":"someField","displayFormat":"%s","type":"STRING","isHeavy":false,"validation":{"required":true},"isHidden":false}},"updatedFrontendStepList":[{"components":[{"type":"EDIT_FORM"}],"name":"inputScreen","formFields":[{"isRequired":false,"isEditable":true,"name":"someField","displayFormat":"%s","type":"STRING","isHeavy":false,"isHidden":false}]},{"components":[{"type":"PROCESS_SUMMARY_RESULTS"}],"name":"resultScreen"}]},"type":"COMPLETE"}},"JOB_STARTED":{"value":{"jobUUID":"98765432-10FE-DCBA-9876-543210FEDCBA","processUUID":"01234567-89AB-CDEF-0123-456789ABCDEF","type":"JOB_STARTED"}},"RUNNING":{"value":{"current":47,"total":1701,"processUUID":"01234567-89AB-CDEF-0123-456789ABCDEF","type":"RUNNING","message":"Processing person records"}},"ERROR":{"value":{"processUUID":"01234567-89AB-CDEF-0123-456789ABCDEF","type":"RUNNING"}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/processes/{processName}/{processUUID}/status/{jobUUID}":{"get":{"summary":"Get job status","description":"Get the status of a running job for a process.\n\nResponse is the same format as for an init or step call that completed synchronously.\n","operationId":"getProcessStatus","tags":["Processes"],"parameters":[{"name":"processName","description":"Name of the process that is being ran","required":true,"in":"path","schema":{"type":"string"},"example":"samplePersonProcess"},{"name":"processUUID","description":"Unique identifier for this run of the process - as was returned by the `init` call.","required":true,"in":"path","schema":{"type":"string","format":"uuid"},"example":"01234567-89AB-CDEF-0123-456789ABCDEF"},{"name":"jobUUID","description":"Unique identifier for the asynchronous job being executed, as returned by an `init` or `step` call that went asynch.","required":true,"in":"path","schema":{"type":"string","format":"uuid"},"example":"98765432-10FE-DCBA-9876-543210FEDCBA"},{"name":"tableVariant","description":"For processes on tables that use variant backends, JSON object naming the variant to use (the same `type` and `id` as in table requests).","required":false,"in":"query","schema":{"type":"string"},"example":"{\"type\":\"store\",\"id\":\"1\"}"}],"responses":{"200":{"description":"State of the backend's running of the specified job, with different fields set,\nbased on the status of the job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProcessStepResponseV1"},"examples":{"COMPLETE":{"value":{"values":{"firstLastName":"Aabramson","totalAge":32768},"processUUID":"01234567-89AB-CDEF-0123-456789ABCDEF","nextStep":"reviewScreen","type":"COMPLETE"}},"COMPLETE with metaDataAdjustment":{"value":{"values":{"firstLastName":"Aabramson","totalAge":32768},"processUUID":"01234567-89AB-CDEF-0123-456789ABCDEF","nextStep":"inputScreen","processMetaDataAdjustment":{"updatedFields":{"someField":{"isRequired":true,"isEditable":true,"name":"someField","displayFormat":"%s","type":"STRING","isHeavy":false,"validation":{"required":true},"isHidden":false}},"updatedFrontendStepList":[{"components":[{"type":"EDIT_FORM"}],"name":"inputScreen","formFields":[{"isRequired":false,"isEditable":true,"name":"someField","displayFormat":"%s","type":"STRING","isHeavy":false,"isHidden":false}]},{"components":[{"type":"PROCESS_SUMMARY_RESULTS"}],"name":"resultScreen"}]},"type":"COMPLETE"}},"JOB_STARTED":{"value":{"jobUUID":"98765432-10FE-DCBA-9876-543210FEDCBA","processUUID":"01234567-89AB-CDEF-0123-456789ABCDEF","type":"JOB_STARTED"}},"RUNNING":{"value":{"current":47,"total":1701,"processUUID":"01234567-89AB-CDEF-0123-456789ABCDEF","type":"RUNNING","message":"Processing person records"}},"ERROR":{"value":{"processUUID":"01234567-89AB-CDEF-0123-456789ABCDEF","type":"RUNNING"}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/processes/{processName}/{processUUID}/records":{"get":{"summary":"Get records from a process","description":"Retrieve the records associated with a running or completed process, with support\nfor pagination via skip and limit query parameters.","operationId":"getProcessRecords","tags":["Processes"],"parameters":[{"name":"processName","description":"Name of the process","required":true,"in":"path","schema":{"type":"string"},"example":"samplePersonProcess"},{"name":"processUUID","description":"Unique identifier for this run of the process","required":true,"in":"path","schema":{"type":"string","format":"uuid"},"example":"01234567-89AB-CDEF-0123-456789ABCDEF"},{"name":"skip","description":"Number of records to skip (default 0)","required":false,"in":"query","schema":{"type":"integer"},"example":"0"},{"name":"limit","description":"Maximum number of records to return (default 20)","required":false,"in":"query","schema":{"type":"integer"},"example":"20"},{"name":"tableVariant","description":"For processes on tables that use variant backends, JSON object naming the variant to use (the same `type` and `id` as in table requests).","required":false,"in":"query","schema":{"type":"string"},"example":"{\"type\":\"store\",\"id\":\"1\"}"}],"responses":{"200":{"description":"Paginated list of records from the process state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProcessRecordsResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/processes/{processName}/{processUUID}/cancel":{"post":{"summary":"Cancel a running process","description":"Cancel a running process. If the process defines a cancel step, it will be executed.","operationId":"cancelProcess","tags":["Processes"],"parameters":[{"name":"processName","description":"Name of the process to cancel","required":true,"in":"path","schema":{"type":"string"},"example":"samplePersonProcess"},{"name":"processUUID","description":"Unique identifier for this run of the process","required":true,"in":"path","schema":{"type":"string","format":"uuid"},"example":"01234567-89AB-CDEF-0123-456789ABCDEF"},{"name":"tableVariant","description":"For processes on tables that use variant backends, JSON object naming the variant to use (the same `type` and `id` as in table requests).","required":false,"in":"query","schema":{"type":"string"},"example":"{\"type\":\"store\",\"id\":\"1\"}"}],"responses":{"200":{"description":"Empty JSON object indicating successful cancellation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProcessCancelResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/processes/{processName}/jobs":{"post":{"summary":"Run a process as a durable background job","description":"Launch an eligible process as a durable job: it survives pod restarts, runs in checkpointed chunks under leases, and can be paused, resumed, cancelled, restarted and retried with the job control processes on the jobs_job table. Values for the process's frontend steps are given up front. The job runs with the caller's permissions (never more). A launch from the assistant client channel waits for confirmation (status AWAITING_CONFIRMATION). Progress arrives as job.progress and job.status events on the realtime channel record:jobs_job:{jobId}.","operationId":"launchProcessJob","tags":["Processes"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","description":"The launch request.","properties":{"values":{"type":"object","description":"Process values (what the frontend steps would have collected)."},"filter":{"type":"object","description":"A records filter (QQueryFilter JSON) the process runs over."},"recordIds":{"type":"array","description":"Primary keys the process runs over.","items":{"type":"string"}},"uploadRefs":{"type":"array","description":"Upload refs from POST /uploads.","items":{"type":"string"}},"savedBulkLoadProfileId":{"type":"integer","description":"A saved bulk load profile to load with."},"profile":{"type":"object","description":"A bulk load profile (BulkLoadProfile v1 JSON) to load with."},"mode":{"type":"string","description":"EXECUTE (default) or VALIDATE (no store).","enum":["EXECUTE","VALIDATE"]},"priority":{"type":"integer","description":"0-9, default 5 (higher runs first)."},"notifyEmail":{"type":"boolean","description":"Email the owner when the job finishes."},"label":{"type":"string","description":"A label for the job (defaults to the process label)."},"startAfterStep":{"type":"string","description":"The launch point: backend steps after this step run in the job."},"expectedRows":{"type":"integer","description":"A known row count (e.g., from a count)."}}}}}},"parameters":[{"name":"processName","description":"Name of the process to run as a job","required":true,"in":"path","schema":{"type":"string"},"example":"person.bulkEdit"}],"responses":{"200":{"description":"The new job's id and status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProcessJobLaunchResponseV1"}}}},"429":{"description":"Too many jobs are waiting for this user (or for the assistant).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/jobs":{"get":{"summary":"Jobs: list","description":"Requires jobs_job.read and the job owner lock; jobs_admin can see all jobs. Hidden jobs return 404; invalid transitions return 409. Progress polls include a twenty-id overlap for concurrent commits; deduplicate log lines by id. Recent jobs finished in the last seven days.","operationId":"listJobs","tags":["Processes"],"parameters":[{"name":"scope","description":"mine (default), or all (requires jobs_admin)","required":false,"in":"query","schema":{"type":"string"}},{"name":"state","description":"active (default), recent, or all","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","description":"1-200; default 50","required":false,"in":"query","schema":{"type":"integer"}},{"name":"processName","description":"Optional process filter","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Job not found or not visible","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"200":{"description":"Job list result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobListResponseV1"}}}},"409":{"description":"Invalid job transition","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/jobs/{jobId}":{"get":{"summary":"Jobs: detail","description":"Requires jobs_job.read and the job owner lock; jobs_admin can see all jobs. Hidden jobs return 404; invalid transitions return 409. Progress polls include a twenty-id overlap for concurrent commits; deduplicate log lines by id. Recent jobs finished in the last seven days.","operationId":"getJob","tags":["Processes"],"parameters":[{"name":"jobId","required":true,"in":"path","schema":{"type":"integer"}}],"responses":{"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Job not found or not visible","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"200":{"description":"Job detail result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobDetailV1"}}}},"409":{"description":"Invalid job transition","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/jobs/{jobId}/progress":{"get":{"summary":"Jobs: progress","description":"Requires jobs_job.read and the job owner lock; jobs_admin can see all jobs. Hidden jobs return 404; invalid transitions return 409. Progress polls include a twenty-id overlap for concurrent commits; deduplicate log lines by id. Recent jobs finished in the last seven days.","operationId":"getJobProgress","tags":["Processes"],"parameters":[{"name":"jobId","required":true,"in":"path","schema":{"type":"integer"}},{"name":"afterLogId","description":"Last observed log id, default 0; response includes a twenty-id overlap","required":false,"in":"query","schema":{"type":"integer"}},{"name":"logLimit","description":"1-200 new lines, plus overlap; default 100","required":false,"in":"query","schema":{"type":"integer"}}],"responses":{"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Job not found or not visible","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"200":{"description":"Job progress result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobProgressPollV1"}}}},"409":{"description":"Invalid job transition","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/jobs/{jobId}/cancel":{"post":{"summary":"Jobs: cancel","description":"Requires jobs_job.read and the job owner lock; jobs_admin can see all jobs. Hidden jobs return 404; invalid transitions return 409. Progress polls include a twenty-id overlap for concurrent commits; deduplicate log lines by id. Recent jobs finished in the last seven days.","operationId":"cancelJob","tags":["Processes"],"parameters":[{"name":"jobId","required":true,"in":"path","schema":{"type":"integer"}}],"responses":{"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Job not found or not visible","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"200":{"description":"Job cancel result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobActionResponseV1"}}}},"409":{"description":"Invalid job transition","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/jobs/{jobId}/retry":{"post":{"summary":"Jobs: retry","description":"Requires jobs_job.read and the job owner lock; jobs_admin can see all jobs. Hidden jobs return 404; invalid transitions return 409. Progress polls include a twenty-id overlap for concurrent commits; deduplicate log lines by id. Recent jobs finished in the last seven days.","operationId":"retryJob","tags":["Processes"],"parameters":[{"name":"jobId","required":true,"in":"path","schema":{"type":"integer"}}],"responses":{"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Job not found or not visible","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"200":{"description":"Job retry result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobActionResponseV1"}}}},"409":{"description":"Invalid job transition","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/jobs/track":{"post":{"summary":"Jobs: track","description":"Requires jobs_job.read and the job owner lock; jobs_admin can see all jobs. Hidden jobs return 404; invalid transitions return 409. Progress polls include a twenty-id overlap for concurrent commits; deduplicate log lines by id. Recent jobs finished in the last seven days.","operationId":"trackJob","tags":["Processes"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobTrackRequestV1"}}}},"responses":{"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Job not found or not visible","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"200":{"description":"Job track result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobActionResponseV1"}}}},"409":{"description":"Invalid job transition","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/uploads":{"post":{"summary":"Upload a file for a job or a bulk load","description":"Streams a file into the application's uploads storage and returns an opaque, expiring ref bound to the caller. Pass the ref in uploadRefs when launching a job (POST /processes/{processName}/jobs). Send multipart form data with one file field, or the raw file as the request body with the fileName query parameter.","operationId":"upload","tags":["Processes"],"requestBody":{"required":false,"content":{"multipart/form-data":{"schema":{"type":"object","description":"One file field.","properties":{"file":{"type":"string","format":"binary","description":"The file."}}}},"application/octet-stream":{"schema":{"type":"string","format":"binary","description":"The raw file (give its name in the fileName query parameter)."}}}},"parameters":[{"name":"fileName","description":"The file's name, when the body is the raw file (not multipart).","required":false,"in":"query","schema":{"type":"string"},"example":"people.csv"}],"responses":{"200":{"description":"The upload's ref, name, size, content type and expiry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadRefResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/export":{"post":{"summary":"Export records from a table","description":"Export records from a table as a downloadable file in the specified format (CSV, XLSX, JSON, TSV).","operationId":"exportTable","tags":["Tables"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"format":{"type":"string","description":"Export format: csv, xlsx, json, tsv"},"filename":{"type":"string","description":"Optional filename for the download. Generated if absent."},"filter":{"description":"QueryFilter to specify matching records to export","$ref":"#/components/schemas/QueryFilter"},"fieldNames":{"type":"array","description":"Optional subset of field names to include in the export","items":{"type":"string"}},"limit":{"type":"integer","description":"Optional maximum number of records to export"},"includeHeaderRow":{"type":"boolean","description":"Whether to include a header row (default true)"},"tableVariant":{"description":"For tables that use variant backends, the variant to export from (the same `type` and `id` as in query requests).","$ref":"#/components/schemas/TableVariant"}}}}}},"parameters":[{"name":"tableName","description":"Name of the table to export.","required":true,"in":"path","schema":{"type":"string"},"example":"person"}],"responses":{"200":{"description":"Binary file content in the requested export format","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/table/{tableName}/{primaryKey}/{fieldName}/{filename}":{"get":{"summary":"Download a field value from a record","description":"Download the binary content of a blob field from a specific record.","operationId":"downloadRecordFieldFile","tags":["Tables"],"parameters":[{"name":"tableName","description":"Name of the table containing the record.","required":true,"in":"path","schema":{"type":"string"},"example":"person"},{"name":"primaryKey","description":"Primary key value of the record.","required":true,"in":"path","schema":{"type":"string"},"example":"42"},{"name":"fieldName","description":"Name of the field to download.","required":true,"in":"path","schema":{"type":"string"},"example":"photo"},{"name":"filename","description":"Filename for the downloaded content.","required":true,"in":"path","schema":{"type":"string"},"example":"photo.jpg"}],"responses":{"200":{"description":"Binary file content","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/download/{file}":{"get":{"summary":"Download a file","description":"Download a file from server-side storage by file path or storage table reference.","operationId":"download","tags":["General"],"parameters":[{"name":"file","description":"Filename for the download.","required":true,"in":"path","schema":{"type":"string"},"example":"report.csv"},{"name":"filePath","description":"Server-side file path to download from.","required":false,"in":"query","schema":{"type":"string"}},{"name":"storageTableName","description":"Name of the storage table to download from.","required":false,"in":"query","schema":{"type":"string"}},{"name":"storageReference","description":"Storage reference key for the file.","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Binary file content","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/reports/{reportName}":{"get":{"summary":"Run a report and download the file","description":"Run a report and stream the generated file in the requested format. The report's input fields are given as\nquery parameters named for the fields; a missing required input is a 400. Requires permission to run the report.","operationId":"runReport","tags":["Reports"],"parameters":[{"name":"reportName","description":"Name of the report to run.","required":true,"in":"path","schema":{"type":"string"},"example":"personReport"},{"name":"format","description":"Output format: csv, xlsx, json (as for table export).","required":true,"in":"query","schema":{"type":"string"},"example":"csv"}],"responses":{"200":{"description":"The generated report file, in the requested format","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/bulkLoad/uploads/{uploadRef}/profile":{"get":{"summary":"Profile an uploaded file for a bulk load","description":"Read an uploaded file (by its upload ref, which must be the session user's) and describe it for a bulk load into a table: whether row 1 is a header row, and each column's inferred type, percent blank, distinct count, maximum length and pattern class. Sample values are included only for columns mapped to an unclassified (or PUBLIC) field, or for every column when the request's `X-QQQ-AI-Route` header is `hipaa`; unmapped columns never get samples otherwise. Requires the table's bulk-insert process permission. Nothing is stored.","operationId":"getBulkLoadUploadProfile","tags":["Bulk Load"],"parameters":[{"name":"uploadRef","description":"The opaque ref of an upload the session user owns.","required":true,"in":"path","schema":{"type":"string"}},{"name":"tableName","description":"The table the file would be loaded into.","required":true,"in":"query","schema":{"type":"string"},"example":"person"},{"name":"sampleCount","description":"Sample values per column, where allowed (0 to 20; default 5).","required":false,"in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"The upload's header guess and column profiles","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkLoadUploadProfileResponseV1"},"examples":{"profile":{"value":{"uploadRef":"u_4f2c","fileName":"people.csv","hasHeaderRow":true,"rowsProfiled":250}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/bulkLoad/{tableName}/suggestMapping":{"post":{"summary":"Suggest a bulk load mapping for an uploaded file","description":"Run the bulk load mapping suggester over an uploaded file's header row and return a v1 bulk load profile, the file columns it leaves unmapped, the required fields it does not fill, and the mapped fields with a possible value source (whose file values may need value mapping). The upload must be the session user's. Requires the table's bulk-insert process permission. Nothing is stored.","operationId":"suggestBulkLoadMapping","tags":["Bulk Load"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"uploadRef":{"type":"string","description":"The opaque ref of an upload the session user owns."},"isBulkEdit":{"type":"boolean","description":"Suggest a bulk edit profile (default false: bulk insert)."}}}}}},"parameters":[{"name":"tableName","description":"The table the file would be loaded into.","required":true,"in":"path","schema":{"type":"string"},"example":"person"}],"responses":{"200":{"description":"The suggested profile and what it leaves unmapped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkLoadSuggestMappingResponseV1"},"examples":{"suggestion":{"value":{"profile":{"version":"v1","layout":"FLAT","hasHeaderRow":true}}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/bulkLoad/{tableName}/validate":{"post":{"summary":"Dry-run a bulk load profile over an uploaded file","description":"Run the table's bulk-insert process over an uploaded file with the given v1 bulk load profile - the same mapping, value mapping and validation a real load uses - and stop at its review step, so nothing is stored. SAMPLE validates the first 100 rows; FULL the whole file. Returns the standard process summary lines, counts, and error groups with row numbers. Values of classified fields are left out unless the request's `X-QQQ-AI-Route` header is `hipaa`. The upload must be the session user's. Requires the table's bulk-insert process permission.","operationId":"validateBulkLoad","tags":["Bulk Load"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"uploadRef":{"type":"string","description":"The opaque ref of an upload the session user owns."},"profile":{"type":"object","description":"A v1 bulk load profile: version, layout (FLAT), hasHeaderRow, and fieldList entries of fieldName, columnIndex, headerName, defaultValue, doValueMapping, valueMappings and clearIfEmpty."},"mode":{"type":"string","description":"SAMPLE (default, the first 100 rows) or FULL.","enum":["SAMPLE","FULL"]}}}}}},"parameters":[{"name":"tableName","description":"The table the file would be loaded into.","required":true,"in":"path","schema":{"type":"string"},"example":"person"}],"responses":{"200":{"description":"The dry run's summary and error groups","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkLoadValidateResponseV1"},"examples":{"dryRun":{"value":{"mode":"SAMPLE","processName":"person.bulkInsert","recordCount":3,"okCount":2,"errorCount":1}}}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/esb/overview":{"get":{"summary":"ESB overview","description":"Every broker connection and destination, with the tables and processes publishing to each and the triggers consuming it, and what the user may do. Needs the ESB app permission.","operationId":"getEsbOverview","tags":["ESB"],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EsbOverviewResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/esb/table/{table}":{"get":{"summary":"ESB of a table","description":"The destinations a table publishes its events to, the triggers subscribed to them (on processes the user can access), and what the user may do. Needs READ on the table.","operationId":"getEsbTableByTable","tags":["ESB"],"parameters":[{"name":"table","description":"Table name.","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EsbTableResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/esb/process/{process}":{"get":{"summary":"ESB of a process","description":"The destinations a process publishes its lifecycle events to, the triggers that run it, and what the user may do. Needs access to the process.","operationId":"getEsbProcessByProcess","tags":["ESB"],"parameters":[{"name":"process","description":"Process name.","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EsbProcessResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/esb/deadLetters/{trigger}":{"get":{"summary":"Dead letters of a trigger","description":"A page of the messages on a trigger dead-letter destination, oldest first. Needs the operate permission.","operationId":"getEsbDeadLettersByTrigger","tags":["ESB"],"parameters":[{"name":"trigger","description":"Trigger name.","required":true,"in":"path","schema":{"type":"string"}},{"name":"offset","description":"Messages to skip (default 0).","required":false,"in":"query","schema":{"type":"integer"}},{"name":"limit","description":"Messages to return (default and maximum set by the server).","required":false,"in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EsbMessagePageResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}},"/qqq/v1/esb/messages/{destination}":{"get":{"summary":"Messages on a destination","description":"A page of the messages waiting on a destination (or, with trigger, on that trigger subscription of a topic), oldest first. Needs the operate permission.","operationId":"getEsbMessagesByDestination","tags":["ESB"],"parameters":[{"name":"destination","description":"Destination name.","required":true,"in":"path","schema":{"type":"string"}},{"name":"trigger","description":"For a topic: the trigger whose subscription to browse.","required":false,"in":"query","schema":{"type":"string"}},{"name":"offset","description":"Messages to skip (default 0).","required":false,"in":"query","schema":{"type":"integer"}},{"name":"limit","description":"Messages to return (default and maximum set by the server).","required":false,"in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EsbMessagePageResponseV1"}}}},"400":{"description":"Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"401":{"description":"Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"403":{"description":"The user (or the credential's scope) may not do this (code PERMISSION_DENIED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"404":{"description":"Not found, or not visible to this user (code NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"409":{"description":"Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}},"429":{"description":"Too many requests (code RATE_LIMITED); retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BasicErrorResponseV1"}}}}},"security":[{"sessionUuidCookie":["N/A"]},{"bearerAuth":["N/A"]},{"oauth2":["openid","profile","email"]}]}}},"components":{"schemas":{"AppMetaData":{"type":"object","properties":{"childMap":{"type":"object","description":"Map of other apps, tables, process, and reports, which are contained within this app. Same contents as the children list, just structured as a map.","additionalProperties":{"$ref":"#/components/schemas/AppTreeNode"}},"children":{"type":"array","description":"List of other apps, tables, process, and reports, which are contained within this app.","items":{"$ref":"#/components/schemas/AppTreeNode"}},"helpContents":{"type":"object","description":"Help entries by slot, filtered for the current session.","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/HelpContentV1"}}},"icon":{"description":"Icon to display for the app.","$ref":"#/components/schemas/Icon"},"keywords":{"type":"array","description":"Search aliases (old labels, jargon, vendor names); match search on label, keywords and ancestor labels; never display","items":{"type":"string"}},"label":{"type":"string","description":"User-facing name for this app"},"name":{"type":"string","description":"Unique name for this app within the QQQ Instance"},"sections":{"type":"array","description":"List of sections - sub-divisions of the app, to further organize its children.","items":{"$ref":"#/components/schemas/AppSection"}},"supplementalAppMetaData":{"type":"object","description":"Additional meta-data describing the app, which may not be known to the QQQ backend core module."},"widgets":{"type":"array","description":"List of widgets names that are part of this app. These strings should be keys to the widgets map in the QQQ Instance.","items":{"type":"string"}}}},"AppSection":{"type":"object","properties":{"apps":{"type":"array","description":"List of child app names for the section","items":{"type":"string"}},"collapsedByDefault":{"type":"boolean","description":"Whether the section is collapsed by default; SETTINGS defaults to true","nullable":true},"icon":{"description":"Icon to display for the section.","$ref":"#/components/schemas/Icon"},"label":{"type":"string","description":"User-facing name of the section."},"name":{"type":"string","description":"Unique (within the app) name for this section."},"processes":{"type":"array","description":"List of process names for the section","items":{"type":"string"}},"reports":{"type":"array","description":"List of report names for the section","items":{"type":"string"}},"role":{"type":"string","description":"PRIMARY: items shown without a heading; HISTORY: system-written records under a heading; SETTINGS: configuration under a heading, collapsed by default; GROUP: a heading grouping child apps, never navigable","enum":["PRIMARY","HISTORY","SETTINGS","GROUP"]},"tables":{"type":"array","description":"List of table names for the section","items":{"type":"string"}}}},"AppTreeNode":{"type":"object","properties":{"children":{"type":"array","description":"Child elements. Only applies for type='app', which contains additional apps under it","items":{"$ref":"#/components/schemas/AppTreeNode"}},"icon":{"description":"Icon to display for the item.","$ref":"#/components/schemas/Icon"},"keywords":{"type":"array","description":"Search aliases (old labels, jargon, vendor names); match search on label, keywords and ancestor labels; never display","items":{"type":"string"}},"label":{"type":"string","description":"User-facing name of the element."},"name":{"type":"string","description":"Unique (within its type) name for this element. e.g., for type = 'table', the table's name."},"type":{"type":"string","description":"The type of node (table, process, report, app)"}}},"AssociatedScriptMetaData":{"type":"object","properties":{"fieldName":{"type":"string","description":"Name of the field, in the record's table, that references the script."},"scriptTypeId":{"type":"object","description":"Id of the script type (a scriptType record) of the scripts this field references."}}},"Association":{"type":"object","properties":{"associatedTableName":{"type":"string","description":"Name of the associated table; its permissions remain independent"},"join":{"type":"object","description":"The named join and field pairs defining this association","properties":{"joinOns":{"type":"array"},"leftTable":{"type":"string"},"name":{"type":"string"},"orderBys":{"type":"array"},"rightTable":{"type":"string"},"type":{"type":"string","enum":["ONE_TO_ONE","ONE_TO_MANY","MANY_TO_ONE","MANY_TO_MANY"]}}},"name":{"type":"string","description":"Exact name used for this group in associatedRecords"}}},"AuditsCapabilityV1":{"type":"object","properties":{"available":{"type":"boolean","description":"True when the user can read this table and its audits one of the two ways (the audit process enforces both). Independent of level: records of a table at level NONE can still have audits written explicitly.","nullable":true},"detailTableName":{"type":"string","description":"The audit detail table (field changes), joined to tableName."},"level":{"type":"string","description":"The table's audit level: NONE, RECORD or FIELD (informational: what is audited automatically)."},"processName":{"type":"string","description":"The process that returns a record's audits (inputs tableName, recordId); absent when the user may not run it."},"tableName":{"type":"string","description":"The audit table, when the user may query it directly."}}},"AuthenticationMetaDataResponseV1":{"type":"object","properties":{"branding":{"type":"object","description":"The application's branding that is safe to show before sign-in (names, logo, icon and accent colors; never\nbanners), so a login page can look like the application. Absent when the instance defines no branding.","properties":{"accentColor":{"type":"string","description":"Primary accent color, as a CSS color value."},"accentColorLight":{"type":"string","description":"Light variant of the accent color, as a CSS color value."},"appName":{"type":"string","description":"Name of this application, for display to users."},"companyName":{"type":"string","description":"Name of the company that operates this application."},"icon":{"type":"string","description":"Path or URL of the application's small icon image."},"logo":{"type":"string","description":"Path or URL of the application's logo image."}}},"dashboardCspSources":{"type":"object","description":"Optional public CSP source additions for standalone dashboards, derived from configured application features; never a full policy or inline script hashes.","properties":{"connectSrc":{"type":"array","description":"HTTP(S) connection sources required by configured features; no default policy sources.","items":{"type":"string"}},"frameSrc":{"type":"array","description":"Frame sources required by configured features.","items":{"type":"string"}},"scriptSrc":{"type":"array","description":"Script sources required by configured features; no inline hashes, nonces or unsafe keywords.","items":{"type":"string"}},"styleSrc":{"type":"array","description":"Style sources required by configured features.","items":{"type":"string"}}}},"name":{"type":"string","description":"Unique name for the authentication metaData object within the QInstance.\n"},"type":{"type":"string","description":"Specifier for the type of authentication module being used.\n\nFrontends should use this value to determine how to prompt the user for authentication credentials.\nIn addition, depending on this value, additional properties will be included in this object, as\nmay be needed to complete the authorization workflow with the provider (e.g., a baseUrl, clientId,\nand audience for an OAuth type workflow)."},"values":{"description":"Additional values, as determined by the type of authentication provider.\n","anyOf":[{"type":"object","description":"No additional values are used for some authentication providers."},{"type":"object","description":"Additional values used by the Auth0 type authentication provider.","properties":{"audience":{"type":"string","description":"Audience for auth0"},"baseUrl":{"type":"string","description":"BaseUrl for auth0"},"clientId":{"type":"string","description":"ClientId for auth0"}}},{"type":"object","description":"Additional values used by the OAuth2 type authentication provider.","properties":{"baseUrl":{"type":"string","description":"BaseUrl for OAuth2 provider"},"bearerTokensAccepted":{"type":"boolean","description":"True when the server accepts the provider's access tokens as Authorization: Bearer . Since 1.6.0.","nullable":true},"clientId":{"type":"string","description":"ClientId for OAuth2 provider"},"nativeClientBaseUrl":{"type":"string","description":"The issuer (OIDC discovery base URL) of nativeClientId, when it differs from baseUrl. Since 1.6.0."},"nativeClientId":{"type":"string","description":"The public OAuth2 client for native clients (CLI, TUI, mobile): use it with auth-code + PKCE or the device-authorization grant, then send the access token as Authorization: Bearer. Absent when the app has no native client. Since 1.6.0."},"scopes":{"type":"string","description":"OAuth2 scopes to request (space-separated)"}}}]}}},"AvatarLookupRequestV1":{"type":"object","description":"The users to look up.","properties":{"userIds":{"type":"array","description":"User ids (as in comments, presence and mentions); at most 200.","items":{"type":"string"}}},"additionalProperties":false},"AvatarLookupResponseV1":{"type":"object","description":"Avatar URLs by user id.","properties":{"avatars":{"type":"object","description":"User id to avatar URL (relative; add size=32|64|128|256). Users without an avatar are absent.","additionalProperties":{"type":"string"}}}},"BackChannelLogoutResponseV1":{"type":"object"},"BasicErrorResponseV1":{"type":"object","description":"The error body of every UI API operation (core and extensions).","properties":{"error":{"type":"string","description":"The error message (the same as message; kept for clients of UI API 1.0 to 1.5)."},"code":{"type":"string","description":"A stable, machine-readable code. Well-known values: BAD_REQUEST (400), UNAUTHENTICATED (401),\nPERMISSION_DENIED (403), NOT_FOUND (404), CONFLICT (409), RATE_LIMITED (429), INTERNAL_ERROR (500),\nERROR (other). Extensions may add codes; treat an unknown code by the HTTP status. Since 1.6.0."},"message":{"type":"string","description":"A message to show the user. Since 1.6.0."},"fieldErrors":{"type":"array","description":"Errors about particular request fields, when known. Since 1.6.0.","items":{"type":"object","properties":{"field":{"type":"string","description":"The field (or parameter) name."},"message":{"type":"string","description":"The error about that field."},"code":{"type":"string","description":"An optional machine-readable code, e.g. REQUIRED, TOO_LONG, PATTERN."}}}},"traceId":{"type":"string","description":"Identifies this request in the server logs (also the X-QQQ-Trace-Id response header); quote it when reporting a problem. Since 1.6.0."}}},"Branding":{"type":"object","properties":{"accentColor":{"type":"string","description":"Primary accent color, as a CSS color value."},"accentColorLight":{"type":"string","description":"Light variant of the accent color, as a CSS color value."},"appName":{"type":"string","description":"Name of this application, for display to users."},"banners":{"type":"object","description":"Banners to display, keyed by the slot where each is shown.","additionalProperties":{"$ref":"#/components/schemas/BrandingBanner"}},"companyName":{"type":"string","description":"Name of the company that operates this application."},"companyUrl":{"type":"string","description":"URL for the company's web site."},"icon":{"type":"string","description":"Path or URL of the application's small icon image."},"logo":{"type":"string","description":"Path or URL of the application's logo image."}}},"BrandingBanner":{"type":"object","properties":{"additionalStyles":{"type":"object","description":"Additional CSS style properties for the banner."},"backgroundColor":{"type":"string","description":"Background color, as a CSS color value."},"messageHTML":{"type":"string","description":"HTML message, used instead of the plain-text message when set."},"messageText":{"type":"string","description":"Plain-text message."},"severity":{"type":"string","description":"Severity of the message: INFO, WARNING, ERROR or SUCCESS."},"textColor":{"type":"string","description":"Text color, as a CSS color value."}}},"BuiltInViewV1":{"type":"object","properties":{"filter":{"type":"object","properties":{"booleanOperator":{"type":"string","enum":["OR"]},"criteria":{"type":"array","items":{"type":"object","properties":{"fieldName":{"type":"string"},"operator":{"type":"string","enum":["EQUALS"]},"values":{"type":"array","items":{"type":"object","description":"The executing session's user id. Display as Me. A missing user matches nothing.","properties":{"type":{"type":"string","enum":["CurrentUser"]}}}}}}}}},"label":{"type":"string"},"name":{"type":"string"}}},"BulkLoadColumnProfile":{"type":"object","properties":{"classification":{"type":"string","description":"Data classification of the mapped field (PUBLIC, CONFIDENTIAL, PII, PHI), or null."},"columnIndex":{"type":"number","description":"Zero-based column index in the file."},"columnLetter":{"type":"string","description":"Spreadsheet-style column letter (A, B, ... AA)."},"distinctCount":{"type":"number","description":"Distinct non-blank values counted (capped at 1000)."},"distinctCountCapped":{"type":"boolean","description":"Whether more distinct values exist than were counted.","nullable":true},"header":{"type":"string","description":"Header text (or Column A, Column B ... when the file has no header row)."},"inferredType":{"type":"string","description":"INTEGER, DECIMAL, BOOLEAN, DATE, DATE_TIME or STRING, from the profiled values."},"mappedFieldName":{"type":"string","description":"The table field the suggested mapping assigns this column to, or null."},"maxLength":{"type":"number","description":"Longest value length."},"patternClass":{"type":"string","description":"DATE_LIKE, EMAIL_LIKE, NUMERIC, CODE_LIKE, TEXT or EMPTY."},"percentBlank":{"type":"number","description":"Percent of profiled rows where the column is blank."},"sampleValues":{"type":"array","description":"Up to sampleCount distinct values, only when samplesAllowed; otherwise empty.","items":{"type":"string"}},"samplesAllowed":{"type":"boolean","description":"Whether sample values may be shown: an AI route of hipaa, or a mapped field that is unclassified or PUBLIC. Unmapped columns are treated as classified.","nullable":true}}},"BulkLoadColumnRef":{"type":"object","properties":{"columnIndex":{"type":"number","description":"Zero-based column index in the file."},"header":{"type":"string","description":"Header text."}}},"BulkLoadFieldRef":{"type":"object","properties":{"fieldName":{"type":"string","description":"Field name."},"label":{"type":"string","description":"Field label."},"possibleValueSourceName":{"type":"string","description":"Possible value source of the field, if any (its file values need mapping)."}}},"BulkLoadRowError":{"type":"object","properties":{"errorCode":{"type":"string","description":"VALUE_TYPE, POSSIBLE_VALUE, DUPLICATE, REQUIRED or OTHER."},"fieldName":{"type":"string","description":"The field the error is about, when known."},"message":{"type":"string","description":"The error message (value-free)."},"rowNumbers":{"type":"string","description":"File rows with the error, e.g. Row 3; Rows 7-9 (no values)."}}},"BulkLoadSuggestMappingResponseV1":{"type":"object","properties":{"profile":{"type":"object","description":"The suggested bulk load profile (v1: version, layout, hasHeaderRow, isBulkEdit, and fieldList entries of fieldName, columnIndex, headerName, defaultValue, doValueMapping, valueMappings, clearIfEmpty)."},"unmappedColumns":{"type":"array","description":"File columns the suggestion does not map.","items":{"$ref":"#/components/schemas/BulkLoadColumnRef"}},"unmappedRequiredFields":{"type":"array","description":"Required table fields the suggestion does not fill.","items":{"$ref":"#/components/schemas/BulkLoadFieldRef"}},"valueMappingFields":{"type":"array","description":"Mapped fields with a possible value source, whose file values may need mapping.","items":{"$ref":"#/components/schemas/BulkLoadFieldRef"}}}},"BulkLoadSummaryLine":{"type":"object","properties":{"bulletsOfText":{"type":"array","description":"Example rows (and their values, unless masked for a classified field).","items":{"type":"string"}},"count":{"type":"number","description":"Number of records the line describes."},"message":{"type":"string","description":"The standard process summary message."},"status":{"type":"string","description":"OK, INFO, WARNING or ERROR."}}},"BulkLoadUploadProfileResponseV1":{"type":"object","properties":{"columns":{"type":"array","description":"The columns.","items":{"$ref":"#/components/schemas/BulkLoadColumnProfile"}},"fileName":{"type":"string","description":"The uploaded file name."},"hasHeaderRow":{"type":"boolean","description":"Whether row 1 looks like a header row (the suggester maps at least one of its values).","nullable":true},"rowsProfiled":{"type":"number","description":"Data rows profiled (up to 1000)."},"uploadRef":{"type":"string","description":"The upload ref."}}},"BulkLoadValidateResponseV1":{"type":"object","properties":{"errorCount":{"type":"number","description":"Records with errors."},"errors":{"type":"array","description":"Error groups with row numbers (up to 100).","items":{"$ref":"#/components/schemas/BulkLoadRowError"}},"jobId":{"type":"number","description":"Reserved: a FULL run over the durable threshold will run as a VALIDATE job and return its id. Always null in this version."},"mode":{"type":"string","description":"SAMPLE (the first 100 rows) or FULL (the whole file)."},"okCount":{"type":"number","description":"Records that would be inserted."},"previewRecordCount":{"type":"number","description":"For SAMPLE, the rows validated."},"processName":{"type":"string","description":"The table's bulk-insert process the dry run used."},"recordCount":{"type":"number","description":"Records read from the file."},"summaryLines":{"type":"array","description":"The standard process summary lines.","items":{"$ref":"#/components/schemas/BulkLoadSummaryLine"}}}},"DeliveryDestinationsResponseV1":{"type":"object","properties":{"destinations":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"label":{"type":"string"},"icon":{"type":"string"},"maxClassification":{"type":"string"},"aboveMaxClassification":{"type":"string"},"order":{"type":"integer"},"maxAttachmentBytes":{"type":"integer","format":"int64"},"allowBearerLinks":{"type":"boolean"}}}}}},"DeliveryOutputResponseV1":{"type":"string","format":"binary"},"DeliveryTargetStepResponseV1":{"type":"object","properties":{"name":{"type":"string"},"label":{"type":"string"},"options":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"}}}},"freeText":{"type":"boolean"},"complete":{"type":"boolean"},"summary":{"type":"string"}}},"DeliveryTargetsRequestV1":{"type":"object","properties":{"chosen":{"type":"object","description":"Selections by delivery target step name; values are provider-defined target identifiers.","additionalProperties":true}}},"EsbCapabilities":{"type":"object","description":"What the provider supports for this destination - show only the actions that are true.","properties":{"browse":{"type":"boolean","description":"Messages can be browsed."},"pauseQueue":{"type":"boolean","description":"The queue can be paused and resumed."},"purge":{"type":"boolean","description":"All messages can be deleted."},"deleteSelected":{"type":"boolean","description":"Selected messages can be deleted."},"deleteOlderThan":{"type":"boolean","description":"Messages older than a time can be deleted."},"move":{"type":"boolean","description":"Messages can be moved to another destination."}}},"EsbCounter":{"type":"object","description":"Activity counters since the server started.","properties":{"published":{"type":"integer","description":"Messages published."},"publishFailures":{"type":"integer","description":"Publish attempts that failed."},"consumed":{"type":"integer","description":"Messages consumed."},"succeeded":{"type":"integer","description":"Consumed messages processed successfully."},"failed":{"type":"integer","description":"Consumed messages that failed."},"retried":{"type":"integer","description":"Redeliveries."},"deadLettered":{"type":"integer","description":"Messages moved to the dead-letter destination."},"inFlight":{"type":"integer","description":"Messages being processed now."},"lastActivity":{"type":"string","format":"date-time","description":"Time of the last activity (ISO-8601), or null.","nullable":true},"avgMs":{"type":"integer","description":"Average processing time in milliseconds."},"maxMs":{"type":"integer","description":"Longest processing time in milliseconds."},"lastError":{"type":"string","description":"The last error message, or null.","nullable":true}}},"EsbDeadLetter":{"type":"object","description":"A dead-letter (or subscription) destination of a trigger.","properties":{"brokerName":{"type":"string","description":"Name on the broker."},"messageCount":{"type":"integer","description":"Messages waiting, or null when unknown.","nullable":true},"paused":{"type":"boolean","description":"Whether it is paused, or null when unknown.","nullable":true}}},"EsbDestination":{"type":"object","description":"A queue or topic.","properties":{"name":{"type":"string","description":"Destination name."},"type":{"type":"string","description":"Destination type.","enum":["QUEUE","TOPIC"]},"provider":{"type":"string","description":"Name of the provider (broker connection)."},"brokerName":{"type":"string","description":"Name of the destination on the broker."},"counters":{"$ref":"#/components/schemas/EsbCounter"},"queueInfo":{"nullable":true,"$ref":"#/components/schemas/EsbQueueInfo"},"capabilities":{"$ref":"#/components/schemas/EsbCapabilities"}}},"EsbMessage":{"type":"object","description":"A message on a destination.","properties":{"messageId":{"type":"string","description":"Broker message id."},"timestamp":{"type":"string","format":"date-time","description":"When it was sent (ISO-8601)."},"deliveryCount":{"type":"integer","description":"Delivery attempts so far."},"event":{"type":"object","description":"The CloudEvents envelope (specversion, id, source, type, time, subject, datacontenttype, data, qqqcausationid), or null when the body is not one.","nullable":true,"additionalProperties":true},"rawBody":{"type":"string","description":"The message body as text."},"properties":{"type":"object","description":"Message properties.","additionalProperties":true}}},"EsbMessagePageResponseV1":{"type":"object","description":"A page of messages.","properties":{"messages":{"type":"array","description":"The messages, oldest first.","items":{"$ref":"#/components/schemas/EsbMessage"}},"hasMore":{"type":"boolean","description":"Whether more messages follow this page."}}},"EsbOverviewDestination":{"description":"A destination with its publishers and triggers.","allOf":[{"$ref":"#/components/schemas/EsbDestination"},{"type":"object","properties":{"publishers":{"type":"array","description":"Tables and processes publishing to it.","items":{"$ref":"#/components/schemas/EsbPublisher"}},"triggers":{"type":"array","description":"Triggers consuming it.","items":{"$ref":"#/components/schemas/EsbTrigger"}}}}]},"EsbOverviewResponseV1":{"type":"object","description":"GET /esb/overview: providers and every destination.","properties":{"providers":{"type":"array","description":"Broker connections.","items":{"$ref":"#/components/schemas/EsbProvider"}},"destinations":{"type":"array","description":"Destinations with their publishers and triggers.","items":{"$ref":"#/components/schemas/EsbOverviewDestination"}},"permissions":{"$ref":"#/components/schemas/EsbPermissions"}}},"EsbPermissions":{"type":"object","description":"What the user may do.","properties":{"canOperate":{"type":"boolean","description":"May pause, resume and retry."},"canDelete":{"type":"boolean","description":"May delete messages."}}},"EsbProcessResponseV1":{"type":"object","description":"GET /esb/process/{process}: what a process publishes, and the triggers that run it.","properties":{"process":{"type":"string","description":"Process name."},"publications":{"type":"array","description":"Destinations the process publishes to.","items":{"$ref":"#/components/schemas/EsbPublication"}},"triggers":{"type":"array","description":"Triggers that run the process.","items":{"$ref":"#/components/schemas/EsbTrigger"}},"permissions":{"$ref":"#/components/schemas/EsbPermissions"}}},"EsbProvider":{"type":"object","description":"A broker connection.","properties":{"name":{"type":"string","description":"Provider name."},"type":{"type":"string","description":"Broker type.","enum":["ACTIVEMQ_ARTEMIS","RABBITMQ"]},"connected":{"type":"boolean","description":"Whether the connection is up."},"managementEnabled":{"type":"boolean","description":"Whether broker management (browse, pause, purge) is available."}}},"EsbPublication":{"type":"object","description":"A destination that a table or process publishes events to.","properties":{"destination":{"$ref":"#/components/schemas/EsbDestination"},"events":{"type":"array","description":"Events published: INSERT, UPDATE or DELETE for tables; STARTED, COMPLETED or FAILED for processes.","items":{"type":"string","description":"Event name."}}}},"EsbPublisher":{"type":"object","description":"A table or process that publishes to a destination.","properties":{"kind":{"type":"string","description":"What publishes.","enum":["TABLE","PROCESS"]},"name":{"type":"string","description":"Table or process name."},"events":{"type":"array","description":"Events published.","items":{"type":"string","description":"Event name."}}}},"EsbQueueInfo":{"type":"object","description":"Broker-reported state of a queue.","properties":{"messageCount":{"type":"integer","description":"Messages waiting."},"consumerCount":{"type":"integer","description":"Connected consumers."},"paused":{"type":"boolean","description":"Whether the queue is paused."}}},"EsbTableResponseV1":{"type":"object","description":"GET /esb/table/{table}: what a table publishes, and who subscribes.","properties":{"table":{"type":"string","description":"Table name."},"publications":{"type":"array","description":"Destinations the table publishes to.","items":{"$ref":"#/components/schemas/EsbPublication"}},"subscribers":{"type":"array","description":"Triggers subscribed to those destinations (on processes the user can access).","items":{"$ref":"#/components/schemas/EsbTrigger"}},"permissions":{"$ref":"#/components/schemas/EsbPermissions"}}},"EsbTrigger":{"type":"object","description":"A process subscribed to a destination.","properties":{"name":{"type":"string","description":"Trigger name."},"processName":{"type":"string","description":"Process the trigger runs."},"processLabel":{"type":"string","description":"User-facing label of the process."},"destination":{"$ref":"#/components/schemas/EsbDestination"},"mode":{"type":"string","description":"SINGLE runs the process per message; BATCH per batch of messages.","enum":["SINGLE","BATCH"]},"concurrency":{"type":"integer","description":"Consumers run in parallel."},"maxAttempts":{"type":"integer","description":"Attempts before a message is dead-lettered."},"state":{"type":"string","description":"Current state of the trigger.","enum":["RUNNING","PAUSED","CONNECTING","STOPPED"]},"counters":{"$ref":"#/components/schemas/EsbCounter"},"deadLetter":{"$ref":"#/components/schemas/EsbDeadLetter"},"subscription":{"nullable":true,"$ref":"#/components/schemas/EsbDeadLetter"}}},"ExposedJoin":{"type":"object","properties":{"isMany":{"type":"boolean","description":"Whether or not this join is 'to many' in nature","nullable":true},"joinPath":{"type":"array","description":"A list of joins that travel from the base table to the exposed join table","items":{"type":"object","properties":{"joinOns":{"type":"array"},"leftTable":{"type":"string"},"name":{"type":"string"},"orderBys":{"type":"array"},"rightTable":{"type":"string"},"type":{"type":"string","enum":["ONE_TO_ONE","ONE_TO_MANY","MANY_TO_ONE","MANY_TO_MANY"]}}}},"joinTable":{"description":"The meta-data for the joined table","$ref":"#/components/schemas/TableMetaData"},"label":{"type":"string","description":"User-facing label to display for this join"}}},"FieldAdornment":{"type":"object","properties":{"type":{"type":"string","description":"Type of this adornment","enum":["LINK","CHIP","SIZE","CODE_EDITOR","RENDER_HTML","REVEAL","FILE_DOWNLOAD","FILE_UPLOAD","TOOLTIP","WIDGET","ERROR","FILE_PREVIEW"]},"values":{"type":"object","description":"Values associated with this adornment. Keys and the meanings of their values differ by type; the known\nkeys are listed (each names the type(s) it applies to). CHIP also uses pattern keys: `color.{fieldValue}`\n(one of default, info, primary, secondary, success, warning, error) and `icon.{fieldValue}` (an icon name),\ngiving the chip colour and icon for a field value. Clients ignore keys they do not know.","properties":{"target":{"type":"string","description":"LINK: where to open the link: _blank for a new window/tab; otherwise the same view."},"toRecordFromTable":{"type":"string","description":"LINK: the field value is a primary key of this table; link to that record (a client navigates to the record view)."},"toRecordFromTableDynamic":{"type":"boolean","description":"LINK: the target table is per record - read it from the record displayValue `{fieldName}:toRecordFromTableDynamic`."},"fileNameField":{"type":"string","description":"FILE_DOWNLOAD, FILE_PREVIEW: the field holding the file name to save or show."},"defaultExtension":{"type":"string","description":"FILE_DOWNLOAD: extension for the saved file when the name has none."},"defaultMimeType":{"type":"string","description":"FILE_DOWNLOAD, FILE_PREVIEW: MIME type to assume when none is known."},"supplementalProcessName":{"type":"string","description":"FILE_DOWNLOAD: process the server runs to produce the file (the client just downloads)."},"supplementalCodeReference":{"type":"object","description":"FILE_DOWNLOAD: code the server runs to produce the file (the client just downloads).","additionalProperties":true},"downloadUrlDynamic":{"type":"boolean","description":"FILE_DOWNLOAD: the download URL is per record - read it from the record displayValue `{fieldName}:downloadUrlDynamic`."},"fileNameFormat":{"type":"string","description":"FILE_DOWNLOAD: format (with %s placeholders) for the saved file name."},"fileNameFormatFields":{"type":"array","description":"FILE_DOWNLOAD: fields whose values fill fileNameFormat, in order.","items":{"type":"string"}},"width":{"type":"string","description":"SIZE: display width of the field - one of xsmall, small, medium, medlarge, large, xlarge (semantic widths; each client maps them to its own columns or characters). FILE_UPLOAD: width of the upload control.","enum":["xsmall","small","medium","medlarge","large","xlarge","full","half"]},"format":{"type":"string","description":"FILE_UPLOAD: control style (dragAndDrop or button)."},"valueIsUploadRef":{"type":"boolean","description":"FILE_UPLOAD: upload the file with POST /uploads and send its ref as the field's value (null removes the file); the value read back is a URL to show. Since 1.8.0."},"accept":{"type":"string","description":"FILE_UPLOAD: accepted MIME types, comma-separated (e.g. image/png,image/jpeg). Since 1.8.0."},"maxBytes":{"type":"integer","description":"FILE_UPLOAD: largest accepted file in bytes. Since 1.8.0."},"imageShape":{"type":"string","description":"FILE_UPLOAD: the field is an image to crop and preview in this shape (square or circle; both crop square). Since 1.8.0.","enum":["square","circle"]},"languageMode":{"type":"string","description":"CODE_EDITOR: language of the code (e.g. javascript, sql, json, velocity) - for highlighting; a client without an editor shows it monospaced."},"staticText":{"type":"string","description":"TOOLTIP: the tooltip text."},"tooltipDynamic":{"type":"boolean","description":"TOOLTIP: the text is per record - read it from the record displayValue `{fieldName}:tooltipDynamic`."},"thumbnailUrlField":{"type":"string","description":"FILE_PREVIEW: field holding a thumbnail image URL."},"fullSizeUrlField":{"type":"string","description":"FILE_PREVIEW: field holding the full-size file URL."},"mimeTypeField":{"type":"string","description":"FILE_PREVIEW: field holding the MIME type (decides image, video, PDF or download-only)."},"altTextField":{"type":"string","description":"FILE_PREVIEW: field holding alternative text."},"captionField":{"type":"string","description":"FILE_PREVIEW: field holding a caption."},"widthField":{"type":"string","description":"FILE_PREVIEW: field holding the pixel width."},"heightField":{"type":"string","description":"FILE_PREVIEW: field holding the pixel height."},"sizeBytesField":{"type":"string","description":"FILE_PREVIEW: field holding the size in bytes."},"thumbnailMaxSize":{"type":"integer","description":"FILE_PREVIEW: largest thumbnail edge in pixels."},"previewable":{"type":"boolean","description":"FILE_PREVIEW: whether the file may be previewed (false: download only)."},"widgetName":{"type":"string","description":"WIDGET: the widget that renders this field."}},"additionalProperties":{}}}},"FieldMetaData":{"type":"object","properties":{"accessTier":{"type":"string","description":"Effective field access: FULL, REVEALABLE, MASKED, or HIDDEN. Omitted means FULL. Restricted values are strings, regardless of field type.","enum":["FULL","REVEALABLE","MASKED","HIDDEN"]},"adornments":{"type":"array","description":"Special UI dressings to add to the field.","items":{"$ref":"#/components/schemas/FieldAdornment"}},"allowedFilterOperators":{"type":"array","description":"Allowed filter operators when restricted: EQUALS and IN for REVEALABLE when exact match is enabled, otherwise empty. Omitted means unrestricted.","items":{"type":"string"}},"behaviors":{"type":"array","description":"Names of the field's behaviors that a frontend applies while editing, e.g., TO_UPPER_CASE, TO_LOWER_CASE or TRIM. Absent when the field has none.","items":{"type":"string"}},"defaultValue":{"type":"string","description":"Default value to use in this field."},"displayFormat":{"type":"string","description":"C-style format specifier for displaying values in this field."},"gridColumns":{"type":"number","description":"Width of this field in a 12-column record form or view grid (e.g., 12 for the full width, 6 for half). Absent when the frontend's default applies."},"helpContents":{"type":"array","description":"Help Contents for this field.","items":{"$ref":"#/components/schemas/HelpContentV1"}},"inlinePossibleValueSource":{"type":"object","description":"Inline possible-value source for this field; enumValues supply choices without a separate lookup.","properties":{"customCodeReference":{"type":"object","properties":{"codeType":{"type":"string","enum":["JAVA","JAVA_SCRIPT"]},"inlineCode":{"type":"string"},"name":{"type":"string"}}},"enumValues":{"type":"array"},"helpContent":{"type":"object"},"idType":{"type":"string","enum":["STRING","INTEGER","LONG","DECIMAL","BOOLEAN","DATE","TIME","DATE_TIME","TEXT","HTML","PASSWORD","BLOB"]},"label":{"type":"string"},"name":{"type":"string"},"orderByFields":{"type":"array"},"overrideIdField":{"type":"string"},"picker":{"type":"object","properties":{"detailFields":{"type":"array"},"filterFields":{"type":"array"},"pageSize":{"type":"number"},"previewField":{"type":"string"},"searchFields":{"type":"array"},"sorts":{"type":"array"},"subtitleFields":{"type":"array"},"thumbnailField":{"type":"string"},"uploadProcessName":{"type":"string"},"uploadResultIdField":{"type":"string"}}},"searchFields":{"type":"array"},"tableName":{"type":"string"},"type":{"type":"string","enum":["ENUM","TABLE","CUSTOM"]},"valueFields":{"type":"array"},"valueFieldsIfNotFound":{"type":"array"},"valueFormat":{"type":"string"},"valueFormatIfNotFound":{"type":"string"}}},"isEditable":{"type":"boolean","description":"Indicate if user may edit the value in this field.","nullable":true},"isHeavy":{"type":"boolean","description":"Indicator of 'heavy' fields, which are not loaded by default. e.g., some blobs or long-texts","nullable":true},"isHidden":{"type":"boolean","description":"Indicate if this field should be hidden from users","nullable":true},"isRequired":{"type":"boolean","description":"Indicate if a value in this field is required.","nullable":true},"isSortable":{"type":"boolean","description":"False for restricted fields; omitted means sortable.","nullable":true},"label":{"type":"string","description":"User-facing name for this field"},"maxLength":{"type":"number","description":"For String fields, the max length the field supports."},"maxValue":{"type":"string","description":"For number fields, the largest value the field accepts (inclusive). Absent when there is no such limit."},"minValue":{"type":"string","description":"For number fields, the smallest value the field accepts (inclusive). Absent when there is no such limit."},"name":{"type":"string","description":"Unique name for this field within its container (table or process)"},"picker":{"type":"object","description":"When this field's possible value source declares a record picker (for sources over large tables), its configuration: thumbnail, preview, subtitle and detail fields, filter fields, search fields, sorts and page size. Frontends offer a searchable, paged picker dialog.","properties":{"detailFields":{"type":"array"},"filterFields":{"type":"array"},"pageSize":{"type":"number"},"previewField":{"type":"string"},"searchFields":{"type":"array"},"sorts":{"type":"array"},"subtitleFields":{"type":"array"},"thumbnailField":{"type":"string"},"uploadProcessName":{"type":"string"},"uploadResultIdField":{"type":"string"}}},"pickerTableName":{"type":"string","description":"When this field has a picker, the table its possible value source reads, whose metadata describes the picker's fields."},"possibleValueSourceDependencyBehavior":{"type":"string","description":"DISABLE_UNTIL_SET disables a contingent field until its dependencies are set (default). SHOW_ALL_UNTIL_SET keeps it enabled and omits criteria with missing inputs in form searches. Absent for non-contingent fields.","enum":["DISABLE_UNTIL_SET","SHOW_ALL_UNTIL_SET"]},"possibleValueSourceDependsOn":{"type":"array","description":"Names of fields controlling this field's choices, including explicit and filter dependencies. Absent for non-contingent fields.","items":{"type":"string"}},"possibleValueSourceName":{"type":"string","description":"If this field's values should come from a possible value source, then that PVS is named here."},"supplementalMetaData":{"type":"object","description":"Additional frontend-visible metadata for this field, keyed by supplemental type."},"type":{"type":"string","description":"Data-type for this field"},"validation":{"description":"The field's validation rules, as the server enforces them on insert and update (required, maxLength and tooLongBehavior, min/max value, pattern). Absent when the field has none. Since 1.6.0.","$ref":"#/components/schemas/FieldValidationV1"}}},"FieldValidationV1":{"type":"object","properties":{"maxInclusive":{"type":"boolean","description":"Whether maxValue itself is accepted (false: the value must be less).","nullable":true},"maxLength":{"type":"number","description":"For string fields, the most characters the field stores. What happens to a longer value is tooLongBehavior."},"maxValue":{"type":"string","description":"For number fields, the largest value accepted (plain digits, exact). See maxInclusive."},"minInclusive":{"type":"boolean","description":"Whether minValue itself is accepted (false: the value must be greater).","nullable":true},"minValue":{"type":"string","description":"For number fields, the smallest value accepted (plain digits, exact). See minInclusive."},"pattern":{"type":"string","description":"A regular expression a non-empty value must match as a whole (written to mean the same in Java and ECMAScript)."},"patternMessage":{"type":"string","description":"The message the server gives for a value that does not match pattern."},"required":{"type":"boolean","description":"True when a value is required.","nullable":true},"tooLongBehavior":{"type":"string","description":"With maxLength: ERROR (a longer value is refused), TRUNCATE or TRUNCATE_ELLIPSIS (it is trimmed on save), PASS_THROUGH (neither)."}}},"FilterCriteria":{"type":"object","properties":{"fieldName":{"type":"string","description":"Field name that this criteria applies to"},"operator":{"type":"string","description":"Logical operator that applies to this criteria","enum":["EQUALS","NOT_EQUALS","NOT_EQUALS_OR_IS_NULL","IN","NOT_IN","IS_NULL_OR_IN","LIKE","NOT_LIKE","STARTS_WITH","ENDS_WITH","CONTAINS","CONTAINS_ALL","NOT_STARTS_WITH","NOT_ENDS_WITH","NOT_CONTAINS","LESS_THAN","LESS_THAN_OR_EQUALS","GREATER_THAN","GREATER_THAN_OR_EQUALS","IS_BLANK","IS_NOT_BLANK","BETWEEN","NOT_BETWEEN","TRUE","FALSE"]},"values":{"type":"array","description":"Values to apply via the operator to the field","items":{"type":"string"}}}},"FormAdjusterOutputV1":{"type":"object","description":"Changes a form adjuster asks the form to apply. Absent or null properties mean no change.","properties":{"updatedFieldMetaData":{"type":"object","description":"Replacement definitions for fields, by field name.","additionalProperties":{"$ref":"#/components/schemas/FieldMetaData"}},"updatedFieldValues":{"type":"object","description":"New values for fields, by field name.","additionalProperties":true},"updatedFieldDisplayValues":{"type":"object","description":"Display values for possible-value fields whose values changed, by field name.","additionalProperties":{"type":"string"}},"fieldsToClear":{"type":"array","description":"Fields whose values should be cleared.","items":{"type":"string"}},"updatedSectionMetaData":{"type":"object","description":"Replacement definitions for form sections, by section name.","additionalProperties":{"$ref":"#/components/schemas/TableSection"}},"isFormDisabled":{"type":"boolean","description":"Whether the form should be disabled."},"formDisabledMessage":{"type":"string","description":"Why the form is disabled."}}},"FrontendComponent":{"type":"object","properties":{"type":{"type":"string","description":"The type of this component. e.g., what kind of UI element(s) should be presented to the user.","enum":["HELP_TEXT","BULK_EDIT_FORM","BULK_LOAD_FILE_MAPPING_FORM","BULK_LOAD_VALUE_MAPPING_FORM","BULK_LOAD_PROFILE_FORM","VALIDATION_REVIEW_SCREEN","EDIT_FORM","VIEW_FORM","DOWNLOAD_FORM","RECORD_LIST","PROCESS_SUMMARY_RESULTS","GOOGLE_DRIVE_SELECT_FOLDER","WIDGET","HTML"]},"values":{"type":"object","description":"Name-value pairs specific to the type of component.","$ref":"#/components/schemas/FrontendComponentValues"}}},"FrontendComponentValues":{"type":"object","description":"These are the known values that can appear in the values map under a FrontendComponent, to control\nhow that component should be presented to the user.\n\nAdditional application-defined properties may appear as well. BULK_EDIT_FORM, BULK_LOAD_FILE_MAPPING_FORM,\nBULK_LOAD_VALUE_MAPPING_FORM, BULK_LOAD_PROFILE_FORM, VALIDATION_REVIEW_SCREEN, VIEW_FORM, DOWNLOAD_FORM,\nRECORD_LIST, PROCESS_SUMMARY_RESULTS and GOOGLE_DRIVE_SELECT_FOLDER have no fixed component-local keys\nsupplied by the core producers; they consume process values and frontend-step metadata.\n\nIn addition, components are expected to use values from an active process's `values` map (e.g., as included in\na `ProcessStepComplete` object), with the following contract between component-types and expected values:\n\n- For component type=`HTML`, there will be a process value with key=`${stepName}.html` (e.g., `resultScreen.html`),\nwhose value is the HTML to display on that screen.\n- For component type=`HELP_TEXT`: There will be a process value with key=`text`, whose value is the text to display on that screen.\nThere may also be a process value with key=`previewText`, which, if present, can be shown before the full text is shown,\ne.g., with a toggle control to hide/show the `text` value.\n","properties":{"blocks":{"type":"array","description":"Components of type=`WIDGET`, which are set as `isAdHocWidget=true`, should include a list of WidgetBlocks in this value.","items":{"$ref":"#/components/schemas/WidgetBlock"}},"includeFieldNames":{"type":"array","description":"Components of type=`EDIT_FORM` can specify a subset of field names to include. This can be used to break a form up into\nsections, by including multiple EDIT_FORM components, with different lists of `includeFieldNames`.\n","items":{"type":"string"}},"isAdHocWidget":{"type":"boolean","description":"Components of type=`WIDGET`, which do not reference a widget defined in the QQQ Instance, but instead,\nare defined as a list of blocks within a frontend step component, will have a this value set to true.","nullable":true},"previewText":{"type":"string","description":"HELP_TEXT: short text shown before expanding the full text."},"sectionLabel":{"type":"string","description":"Components of type=`EDIT_FORM` can specify a user-facing text label to show on screen.\n"},"text":{"type":"string","description":"HELP_TEXT: text shown by the component."},"widgetName":{"type":"string","description":"Components of type=`WIDGET`, which should render a widget defined in the QQQ instance, this value specifies\nthe name of that widget. Contrast with ad-hoc widgets.\n"}}},"FrontendStep":{"type":"object","properties":{"backStepName":{"type":"string","description":"Name of the step a user can go back to from this step (step with isStepBack=true), when there is one."},"components":{"type":"array","description":"The components that make up this screen","items":{"$ref":"#/components/schemas/FrontendComponent"}},"formFields":{"type":"array","description":"Fields used as form fields (inputs) on this step/screen","items":{"$ref":"#/components/schemas/FieldMetaData"}},"format":{"type":"string","description":"An optional indicator of the screen format preferred by the application to be used for this screen. Different frontends may support different formats, and implement them differently."},"helpContents":{"type":"array","description":"Help content shown on the step/screen.","items":{"$ref":"#/components/schemas/HelpContentV1"}},"label":{"type":"string","description":"The user-facing name for this step"},"name":{"type":"string","description":"The unique name for this step within its process"},"recordListFields":{"type":"array","description":"Fields used in record-lists shown on the step/screen.","items":{"$ref":"#/components/schemas/FieldMetaData"}},"viewFields":{"type":"array","description":"Fields used as view-only fields on this step/screen","items":{"$ref":"#/components/schemas/FieldMetaData"}}}},"HelpContentV1":{"type":"object","properties":{"content":{"type":"string","description":"Long help in the declared format."},"contentAsHtml":{"type":"string","description":"Rendered Markdown (raw HTML escaped, unsafe links removed). Explicit HTML is unchanged and clients must sanitize it."},"contentAsText":{"type":"string","description":"Plain-text help, preserving link text and line breaks."},"format":{"type":"string","description":"Format of the long help.","enum":["TEXT","HTML","MARKDOWN"]},"roles":{"type":"array","description":"Screen roles covered by this entry.","items":{"type":"string"}},"summary":{"type":"string","description":"Optional short plain-text tooltip."}}},"HelpCoverageEntryV1":{"type":"object","properties":{"hasContent":{"type":"boolean","description":"Whether visible help has long content.","nullable":true},"hasSummary":{"type":"boolean","description":"Whether visible help has an explicit summary.","nullable":true},"hidden":{"type":"boolean","description":"Whether the target is hidden in metadata.","nullable":true},"key":{"type":"string","description":"Canonical helpContent address."},"kind":{"type":"string","description":"Help target kind."},"label":{"type":"string","description":"User-facing target label."},"parentKey":{"type":"string","description":"Canonical parent address."},"roles":{"type":"array","description":"Screen roles covered by this entry.","items":{"type":"string"}}}},"HelpCoverageResponseV1":{"type":"object","properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/HelpCoverageEntryV1"}},"totals":{"type":"array","items":{"$ref":"#/components/schemas/HelpCoverageTotalV1"}}}},"HelpCoverageTotalV1":{"type":"object","properties":{"kind":{"type":"string","description":"Help target kind."},"total":{"type":"number","description":"Number of targets in the selected kind and parent scope."},"withHelp":{"type":"number","description":"Targets with a visible summary or long content."}}},"HelpSearchResponseV1":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/HelpSearchResultV1"}}}},"HelpSearchResultV1":{"type":"object","properties":{"contentAsHtml":{"type":"string","description":"Rendered Markdown (raw HTML escaped, unsafe links removed). Explicit HTML is unchanged and clients must sanitize it."},"contentAsText":{"type":"string","description":"Plain-text help, preserving link text and line breaks."},"href":{"type":"string","description":"Application-relative navigation link, when available."},"key":{"type":"string","description":"Canonical helpContent address."},"kind":{"type":"string","description":"Help target kind."},"label":{"type":"string","description":"User-facing target label."},"name":{"type":"string","description":"Target metadata name."},"process":{"type":"string","description":"Related process name, when applicable."},"summary":{"type":"string","description":"Optional short plain-text tooltip."},"table":{"type":"string","description":"Related table name, when applicable."},"text":{"type":"string","description":"Plain-text help excerpt, at most 600 characters."}}},"Icon":{"type":"object","properties":{"color":{"type":"string","description":"A color code to use for displaying the icon"},"name":{"type":"string","description":"Material UI icon name (web); prefer semanticName"},"path":{"type":"string","description":"A path to an image file that can be requested from the server, to serve as the icon image instead of a material UI icon."},"semanticName":{"type":"string","description":"Client-neutral kebab-case icon token; null when unmapped."}}},"JobActionResponseV1":{"type":"object","properties":{"jobId":{"type":"number"}}},"JobDetailV1":{"type":"object","properties":{"actions":{"type":"array","items":{"type":"string"}},"bytesDone":{"type":"number"},"bytesTotal":{"type":"number"},"chunksDone":{"type":"number"},"chunksTotal":{"type":"number"},"currentPhase":{"type":"string"},"etaSeconds":{"type":"number"},"finishedAt":{"type":"string"},"jobId":{"type":"number"},"label":{"type":"string"},"logSeq":{"type":"number"},"message":{"type":"string"},"percent":{"type":"number"},"processName":{"type":"string"},"progress":{"type":"object","properties":{"bytesDone":{"type":"number"},"bytesTotal":{"type":"number"},"currentPhase":{"type":"string"},"done":{"type":"number"},"etaSeconds":{"type":"number"},"message":{"type":"string"},"percent":{"type":"number"},"phases":{"type":"array","items":{"$ref":"#/components/schemas/JobPhaseV1"}},"total":{"type":"number"},"unitLabel":{"type":"string"},"updatedAt":{"type":"string"}}},"queuedAt":{"type":"string"},"rowsDone":{"type":"number"},"rowsFailed":{"type":"number"},"rowsTotal":{"type":"number"},"sourceType":{"type":"string"},"startedAt":{"type":"string"},"status":{"type":"string"},"summary":{"type":"object"},"userId":{"type":"string"}}},"JobListResponseV1":{"type":"object","properties":{"activeCount":{"type":"number"},"generatedAt":{"type":"string"},"jobs":{"type":"array","items":{"$ref":"#/components/schemas/JobSummaryV1"}}}},"JobLogLineV1":{"type":"object","properties":{"attempt":{"type":"number"},"chunkId":{"type":"number"},"id":{"type":"number"},"jobId":{"type":"number"},"level":{"type":"string"},"loggedAt":{"type":"string"},"message":{"type":"string"},"phase":{"type":"string"}}},"JobPhaseV1":{"type":"object","properties":{"label":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"weight":{"type":"number"}}},"JobProgressPollV1":{"type":"object","properties":{"job":{"type":"object","properties":{"bytesDone":{"type":"number"},"bytesTotal":{"type":"number"},"chunksDone":{"type":"number"},"chunksTotal":{"type":"number"},"currentPhase":{"type":"string"},"etaSeconds":{"type":"number"},"finishedAt":{"type":"string"},"jobId":{"type":"number"},"label":{"type":"string"},"logSeq":{"type":"number"},"message":{"type":"string"},"percent":{"type":"number"},"processName":{"type":"string"},"queuedAt":{"type":"string"},"rowsDone":{"type":"number"},"rowsFailed":{"type":"number"},"rowsTotal":{"type":"number"},"sourceType":{"type":"string"},"startedAt":{"type":"string"},"status":{"type":"string"},"userId":{"type":"string"}}},"log":{"type":"array","items":{"$ref":"#/components/schemas/JobLogLineV1"}},"logDropped":{"type":"number"},"nextAfterLogId":{"type":"number"},"progress":{"type":"object","properties":{"bytesDone":{"type":"number"},"bytesTotal":{"type":"number"},"currentPhase":{"type":"string"},"done":{"type":"number"},"etaSeconds":{"type":"number"},"message":{"type":"string"},"percent":{"type":"number"},"phases":{"type":"array","items":{"$ref":"#/components/schemas/JobPhaseV1"}},"total":{"type":"number"},"unitLabel":{"type":"string"},"updatedAt":{"type":"string"}}},"terminal":{"type":"boolean","nullable":true}}},"JobProgressV1":{"type":"object","properties":{"bytesDone":{"type":"number"},"bytesTotal":{"type":"number"},"currentPhase":{"type":"string"},"done":{"type":"number"},"etaSeconds":{"type":"number"},"message":{"type":"string"},"percent":{"type":"number"},"phases":{"type":"array","items":{"$ref":"#/components/schemas/JobPhaseV1"}},"total":{"type":"number"},"unitLabel":{"type":"string"},"updatedAt":{"type":"string"}}},"JobSummaryV1":{"type":"object","properties":{"bytesDone":{"type":"number"},"bytesTotal":{"type":"number"},"chunksDone":{"type":"number"},"chunksTotal":{"type":"number"},"currentPhase":{"type":"string"},"etaSeconds":{"type":"number"},"finishedAt":{"type":"string"},"jobId":{"type":"number"},"label":{"type":"string"},"logSeq":{"type":"number"},"message":{"type":"string"},"percent":{"type":"number"},"processName":{"type":"string"},"queuedAt":{"type":"string"},"rowsDone":{"type":"number"},"rowsFailed":{"type":"number"},"rowsTotal":{"type":"number"},"sourceType":{"type":"string"},"startedAt":{"type":"string"},"status":{"type":"string"},"userId":{"type":"string"}}},"JobTrackRequestV1":{"type":"object","properties":{"jobUUID":{"type":"string"},"processName":{"type":"string"},"processUUID":{"type":"string"}}},"LogoutResponseV1":{"type":"object"},"ManageSessionResponseV1":{"type":"object","properties":{"uuid":{"type":"string","description":"Unique identifier of the session. Required to be returned on subsequent requests in the sessionUUID Cookie, to prove authentication. Not included when the cookie is HttpOnly or the session was resumed from that cookie."},"values":{"type":"object","description":"Optional object with application-defined values. `user` describes the signed-in user: `name`, `email` or `username` (by authentication module), and, when the application installs user profiles (since 1.8.0), `displayName` (the name the user chose; prefer it to `name`) and `avatarUrl` (relative URL of GET /avatars/{avatarId} with its version; add `&size=32|64|128|256`). No `avatarUrl` means draw initials.","additionalProperties":true}}},"MaterialDashboardInstanceSettings":{"type":"object","properties":{"processNamesToAddToAllQueryAndViewScreens":{"type":"array","description":"Names of processes to offer on the query and record-view screens of every table, in their configured order. Only processes that the user may see (i.e., that are in the meta-data's `processes` map) are listed, so the list may be empty.","items":{"type":"string"}},"recordViewActionsPlacement":{"type":"string","description":"Where the record view puts its actions: IN_IDENTITY_SECTION or INLINE_WITH_PAGE_TITLE. When set, this overrides each table's placement."},"weekdayCriteriaSettings":{"description":"Weekday criteria settings for the query screens (day is any of, day is none of). Omitted when the material dashboard meta-data does not define them.","$ref":"#/components/schemas/MaterialDashboardWeekdayCriteriaSettings"}}},"MaterialDashboardWeekdayCriteriaSettings":{"type":"object","properties":{"dateTimeFieldFunctionArguments":{"type":"object","description":"Arguments for the WeekdayOfDateTime field function that a frontend sends with weekday criteria on date-time fields (for example timeZoneId or useSessionZoneId).","$ref":"#/components/schemas/WeekdayCriteriaArguments"},"enabled":{"type":"boolean","description":"Whether query screens offer the weekday criteria (day is any of, day is none of) on date and date-time fields.","nullable":true}}},"MetaDataResponseV1":{"type":"object","properties":{"appTree":{"type":"array","description":"Tree of apps within the QQQ Instance, sorted and organized hierarchically, for presentation to a user.","items":{"$ref":"#/components/schemas/AppTreeNode"}},"apps":{"type":"object","description":"Map of all apps within the QQQ Instance (that the user has permission to see that they exist).","additionalProperties":{"$ref":"#/components/schemas/AppMetaData"}},"branding":{"type":"object","description":"Application identity (names, logo, icon, accent colors and banners), when the instance defines it.","properties":{"accentColor":{"type":"string","description":"Primary accent color, as a CSS color value."},"accentColorLight":{"type":"string","description":"Light variant of the accent color, as a CSS color value."},"appName":{"type":"string","description":"Name of this application, for display to users."},"banners":{"type":"object","description":"Banners to display, keyed by the slot where each is shown.","additionalProperties":{"$ref":"#/components/schemas/BrandingBanner"}},"companyName":{"type":"string","description":"Name of the company that operates this application."},"companyUrl":{"type":"string","description":"URL for the company's web site."},"icon":{"type":"string","description":"Path or URL of the application's small icon image."},"logo":{"type":"string","description":"Path or URL of the application's logo image."}}},"environmentValues":{"type":"object","description":"Environment values a frontend may use: Google Picker public browser settings GOOGLE_APP_CLIENT_ID and GOOGLE_APP_API_KEY, and the analytics settings (ANALYTICS_PROVIDERS, ANALYTICS_PLUGIN_SCRIPTS, ANALYTICS_PLUGIN_SCRIPT_URLS, GOOGLE_ANALYTICS_ENABLED, GOOGLE_ANALYTICS_TRACKING_ID, POSTHOG_ENABLED, POSTHOG_API_KEY, POSTHOG_PROJECT_API_KEY, POSTHOG_HOST, and any other ANALYTICS_* value), from the instance's QQQ_ENV_* environment. An explicit allow-list - never the whole environment. Omitted when none are set.","additionalProperties":{"type":"string"}},"helpContents":{"type":"object","description":"Instance-level help content, by slot name (for example the query screen's bulkAddFilterValues and bulkAddFilterValuesPossibleValueSource slots). Omitted when the instance defines none.","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/HelpContentV1"}}},"homeAppName":{"type":"string","description":"Name of the app whose dashboard a frontend shows as the instance's home page (for example at /app/), when the instance designates one and the user may access that app. Omitted otherwise, in which case the frontend uses its own default home page."},"metaDataGeneration":{"type":"number"},"processes":{"type":"object","description":"Map of all processes within the QQQ Instance (that the user has permission to see that they exist).","additionalProperties":{"$ref":"#/components/schemas/ProcessMetaDataLight"}},"reports":{"type":"object","description":"Map of all reports within the QQQ Instance (that the user has permission to see that they exist).","additionalProperties":{"type":"object","properties":{"hasPermission":{"type":"boolean","description":"Whether the user may run the report."},"helpContents":{"type":"object","description":"Help entries by slot, filtered for the current session.","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/HelpContentV1"}}},"iconName":{"type":"string","description":"Material UI icon name (web); prefer iconSemanticName"},"iconSemanticName":{"type":"string","description":"Client-neutral kebab-case icon token; null when unmapped."},"label":{"type":"string","description":"User-facing name for this report."},"name":{"type":"string","description":"Unique name for this report within the QQQ Instance."},"processName":{"type":"string","description":"Process that runs this report, when it has one; otherwise it runs from GET /reports/{reportName}."}}}},"supplementalInstanceMetaData":{"type":"object","description":"Settings from supplemental modules that a frontend may use (an explicit allow-list - not the supplemental meta-data objects themselves). Omitted when the instance defines none of them.","properties":{"assistant":{"type":"object","description":"Present (an object) when the instance has the assistant QBit's `assistant` supplemental meta-data - that is, when the assistant is installed and enabled, so a frontend may probe its routes. Always has `available: true`, plus the strings, numbers and booleans the QBit publishes for frontends.","additionalProperties":true},"materialDashboard":{"type":"object","description":"Use uiSettings; kept for Next UI until it migrates","properties":{"processNamesToAddToAllQueryAndViewScreens":{"type":"array","description":"Names of processes to offer on the query and record-view screens of every table, in their configured order. Only processes that the user may see (i.e., that are in the meta-data's `processes` map) are listed, so the list may be empty.","items":{"type":"string"}},"recordViewActionsPlacement":{"type":"string","description":"Where the record view puts its actions: IN_IDENTITY_SECTION or INLINE_WITH_PAGE_TITLE. When set, this overrides each table's placement."},"weekdayCriteriaSettings":{"type":"object","description":"Weekday criteria settings for the query screens (day is any of, day is none of). Omitted when the material dashboard meta-data does not define them.","properties":{"dateTimeFieldFunctionArguments":{"type":"object","description":"Arguments for the WeekdayOfDateTime field function that a frontend sends with weekday criteria on date-time fields (for example timeZoneId or useSessionZoneId).","$ref":"#/components/schemas/WeekdayCriteriaArguments"},"enabled":{"type":"boolean","description":"Whether query screens offer the weekday criteria (day is any of, day is none of) on date and date-time fields.","nullable":true}}}},"deprecated":true},"materialDashboardTheme":{"type":"object","description":"Use uiSettings; kept for Next UI until it migrates. The application theme from the instance's MaterialDashboardThemeMetaData supplemental meta-data, when the instance defines it. Keys are MaterialDashboardThemeMetaData property names (for example primaryColor, fontFamily, typographyH1FontSize, borderRadiusGlobal, density, customCss, brandedHeaderEnabled, sidebarBackgroundColor, tableHeaderBackgroundColor); values are strings, numbers or booleans. An explicit allow-list of the theme's visual properties; properties without a value are omitted.","additionalProperties":true,"deprecated":true},"uiSettings":{"type":"object","description":"Client-neutral process, query, record-view and theme settings.","properties":{"processNamesToAddToAllQueryAndViewScreens":{"type":"array","description":"Visible processes offered on every query and record-view screen.","items":{"type":"string"}},"recordViewActionsPlacement":{"type":"string","description":"Placement of record-view actions."},"theme":{"type":"object","description":"Configured colors and font families; no web layout or CSS settings.","additionalProperties":{"type":"string"}},"weekdayCriteriaSettings":{"type":"object","description":"Weekday query criteria configuration.","properties":{"dateTimeFieldFunctionArguments":{"type":"object","description":"Arguments for the WeekdayOfDateTime field function that a frontend sends with weekday criteria on date-time fields (for example timeZoneId or useSessionZoneId).","$ref":"#/components/schemas/WeekdayCriteriaArguments"},"enabled":{"type":"boolean","description":"Whether query screens offer the weekday criteria (day is any of, day is none of) on date and date-time fields.","nullable":true}}}}}}},"tables":{"type":"object","description":"Map of all tables within the QQQ Instance (that the user has permission to see that they exist).","additionalProperties":{"$ref":"#/components/schemas/TableMetaDataLight"}},"widgets":{"type":"object","description":"Map of all widgets within the QQQ Instance (that the user has permission to see that they exist).","additionalProperties":{"type":"object","properties":{"defaultValues":{"type":"object","description":"Frontend widget defaults, including explicit association bindings","additionalProperties":true},"dropdowns":{"type":"array","description":"Dropdowns the widget offers to filter its data."},"footerHTML":{"type":"string","description":"HTML shown below the widget."},"footerText":{"type":"string","description":"Plain-text footer, preserving link text and line breaks."},"gridColumns":{"type":"number","description":"Number of grid columns (of 12) the widget spans."},"hasPermission":{"type":"boolean","description":"Whether the user may render the widget."},"helpContent":{"type":"object","description":"Help content by slot.","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/HelpContentV1"}}},"icon":{"type":"string","description":"Name of the widget's icon."},"icons":{"type":"object","description":"Icons by role (for example the widget header icon).","additionalProperties":true},"isCard":{"type":"boolean","description":"Whether the widget is drawn as a card."},"label":{"type":"string","description":"User-facing name for this widget"},"minHeight":{"type":"string","description":"Minimum height of the widget (a CSS length)."},"name":{"type":"string","description":"Unique name for this widget within the QQQ Instance"},"showExportButton":{"type":"boolean","description":"Whether the widget offers an export button."},"showReloadButton":{"type":"boolean","description":"Whether the widget offers a reload button."},"storeDropdownSelections":{"type":"boolean","description":"Whether dropdown selections are remembered for the user."},"tooltip":{"type":"string","description":"Tooltip text for the widget."},"type":{"type":"string","description":"The type of this widget."}}}}}},"OrderBy":{"type":"object","properties":{"fieldName":{"type":"string","description":"Field name that this order-by applies to"},"isAscending":{"type":"boolean","description":"Whether this order-by is ascending or descending","nullable":true}}},"OutputRecord":{"type":"object","properties":{"associatedRecords":{"type":"object","description":"Records associated with this record, keyed by association name. Each value is a list of records with the same shape as this one. Only present when associations were requested or written.","additionalProperties":{"type":"array"}},"displayValues":{"type":"object","description":"Formatted string versions of the values that make up the record. Keys are Strings, which match the table's field names. Values are all Strings."},"errors":{"type":"array","description":"Messages for errors on this record (for example on an associated record that could not be written). Omitted when there are none.","items":{"type":"string"}},"recordLabel":{"type":"string","description":"Label to identify the record to a user."},"tableName":{"type":"string","description":"Name of the table that the record is from."},"values":{"type":"object","description":"Raw values that make up the record. Keys are Strings, which match the table's field names. Values can be any type, as per the table's fields. Single-record responses (get, insert, update) include fields whose value is null; query results omit them."},"warnings":{"type":"array","description":"Messages for warnings on this record. Omitted when there are none.","items":{"type":"string"}}}},"PossibleValueOption":{"type":"object","properties":{"displayValues":{"type":"object","description":"For a picker request: formatted or translated display values, where they differ from the raw values"},"id":{"type":"object","description":"Unique identifier for this possible value option"},"label":{"type":"string","description":"Human-readable label for this possible value option"},"values":{"type":"object","description":"For a picker request: the option's picker display values (thumbnail, preview, subtitle and detail fields), raw"}}},"PossibleValuesResponseV1":{"type":"object","properties":{"hasMore":{"type":"boolean","description":"For a picker request: whether another page of options follows (the picker never counts)","nullable":true},"options":{"type":"array","description":"List of possible value options matching the search request","items":{"$ref":"#/components/schemas/PossibleValueOption"}}}},"PreferenceActionRequestV1":{"type":"object","description":"Only rowKey and values are accepted. Identity always comes from the authenticated session.","properties":{"rowKey":{"type":"string","description":"Required for ROW actions: a key loaded for this user with the action allowed. Forbidden for SECTION and LIST actions."},"values":{"type":"object","description":"Action input fields. Validated and coerced like PATCH fields; unknown fields are rejected.","additionalProperties":{}}},"additionalProperties":false},"PreferenceActionResponseV1":{"type":"object","description":"Action result and reloaded section. Secrets are shown once and must not be stored by clients. Response uses Cache-Control: no-store.","properties":{"section":{"$ref":"#/components/schemas/PreferenceSectionV1"},"message":{"type":"string","description":"User-facing outcome message."},"secrets":{"type":"array","description":"One-time secrets for immediate display; clients must not store them.","items":{"$ref":"#/components/schemas/PreferenceSecretV1"}},"focusRowKey":{"type":"string","description":"Optional row key to focus after reloading the section."}}},"PreferenceActionV1":{"type":"object","properties":{"name":{"type":"string","description":"Stable action name used in URLs."},"label":{"type":"string","description":"Human-readable action label."},"icon":{"$ref":"#/components/schemas/Icon"},"description":{"type":"string","description":"Explanation for clients to display."},"scope":{"type":"string","description":"Where to display this action. ROW actions require a loaded row key.","enum":["SECTION","LIST","ROW"]},"listName":{"type":"string","description":"List targeted by LIST or ROW actions; null for SECTION.","nullable":true},"confirmationText":{"type":"string","description":"When set, clients must confirm with this text before running the action.","nullable":true},"isDestructive":{"type":"boolean","description":"Whether clients should present this as a destructive action."},"inputFields":{"type":"array","description":"Action inputs, using preference field validation and coercion.","items":{"$ref":"#/components/schemas/FieldMetaData"}},"order":{"type":"integer","description":"Display order, ascending then label; defaults to 100."}}},"PreferenceListV1":{"type":"object","description":"A list of fixed preference rows, rendered with the same typed field editors as scalar preferences.","properties":{"name":{"type":"string","description":"List name used in PATCH lists."},"label":{"type":"string","description":"Human-readable list title."},"description":{"type":"string","description":"Explanation of this list."},"rowLabel":{"type":"string","description":"Label for one row, such as Category."},"fields":{"type":"array","description":"Editable columns and their validation rules.","items":{"$ref":"#/components/schemas/FieldMetaData"}},"rows":{"type":"array","description":"Fixed rows available to this user.","items":{"$ref":"#/components/schemas/PreferenceRowV1"}}}},"PreferenceRowV1":{"type":"object","description":"A provider-owned row. Clients change row membership only through registered actions.","properties":{"actionNames":{"type":"array","description":"Null allows every ROW action of this list; empty allows none; otherwise only the named actions are allowed.","items":{"type":"string"},"nullable":true},"key":{"type":"string","description":"Stable provider row key to send when patching."},"label":{"type":"string","description":"Human-readable row label."},"description":{"type":"string","description":"Explanation of this row."},"values":{"type":"object","description":"Field name to typed value. Omitted fields retain their existing values; explicit null clears an optional field.","additionalProperties":{}},"readOnlyFields":{"type":"array","description":"Field names that cannot be changed for this row.","items":{"type":"string"}},"readOnlyReason":{"type":"string","description":"Explain why the indicated fields are read-only."}}},"PreferenceSecretV1":{"type":"object","properties":{"label":{"type":"string","description":"Human-readable secret label."},"value":{"type":"string","description":"Shown once. Clients must not store, log, cache, or send this secret to analytics."},"masked":{"type":"string","description":"Masked representation, for example qqq_…7f3a."},"usageText":{"type":"string","description":"Usage guidance such as a curl example; may contain newlines."}}},"PreferenceSectionPatchRequestV1":{"type":"object","description":"Partial update for the signed-in user only. Unknown properties, fields, lists and rows, including userId, are rejected with 400. All validation errors are returned together; omitted fields and rows are unchanged.","properties":{"values":{"type":"object","description":"Changed scalar fields only. Explicit null clears an optional field. Types, required, maxLength, ENUM membership and editability are validated.","additionalProperties":{}},"lists":{"type":"object","description":"List name to changed fixed rows. No add or remove operation is supported.","additionalProperties":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"Required fixed row key from the section response. No new rows can be created."},"values":{"type":"object","description":"Changed row fields only. Read-only fields are rejected.","additionalProperties":{}}},"additionalProperties":false}}}},"additionalProperties":false},"PreferenceSectionV1":{"type":"object","description":"One visible section with the signed-in user's current preferences.","properties":{"showInUserMenu":{"type":"boolean","description":"Add a user-menu entry using the section label and icon to open this section; defaults to false."},"name":{"type":"string","description":"Stable section name used in URLs."},"label":{"type":"string","description":"Human-readable section title."},"description":{"type":"string","description":"Explanation for clients to display."},"appName":{"type":"string","description":"Optional owning application name."},"icon":{"$ref":"#/components/schemas/Icon"},"order":{"type":"integer","description":"Display order, ascending then label; defaults to 100."},"fields":{"type":"array","description":"Scalar field definitions with editability, type, defaults and validation.","items":{"$ref":"#/components/schemas/FieldMetaData"}},"values":{"type":"object","description":"Field name to typed value. Omitted fields retain their existing values; explicit null clears an optional field.","additionalProperties":{}},"actions":{"type":"array","description":"Registered section, list and row actions, ordered by order then label.","items":{"$ref":"#/components/schemas/PreferenceActionV1"}},"lists":{"type":"array","description":"Optional fixed-row preference lists.","items":{"$ref":"#/components/schemas/PreferenceListV1"}},"possibleValues":{"type":"object","description":"Every ENUM possible-value source referenced by scalar, list or action input fields, keyed by source name.","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/PossibleValueOption"}}}}},"PreferencesResponseV1":{"type":"object","description":"Visible sections in display order, with only the signed-in user's values.","properties":{"sections":{"type":"array","description":"Installed sections the session may access; an empty list is valid.","items":{"$ref":"#/components/schemas/PreferenceSectionV1"}}}},"ProcessCancelResponseV1":{"type":"object"},"ProcessCapabilityV1":{"type":"object","properties":{"available":{"type":"boolean","description":"True when the process exists and the user may run it.","nullable":true},"processName":{"type":"string","description":"The process to run (present only when available)."}}},"ProcessJobLaunchResponseV1":{"type":"object","properties":{"jobId":{"type":"number","description":"Id of the new durable job (a jobs_job record; read it with GET /table/jobs_job/{jobId})."},"status":{"type":"string","description":"Status of the new job: QUEUED, or AWAITING_CONFIRMATION for a launch from the assistant channel."}}},"ProcessMetaData":{"type":"object","properties":{"durableJobAlways":{"type":"boolean","description":"True when the process always runs as a durable background job (too large to run while the user waits).","nullable":true},"durableJobEligible":{"type":"boolean","description":"True when the process can run as a durable background job (POST /processes/{processName}/jobs): clients may offer \"Run in background\".","nullable":true},"frontendSteps":{"type":"array","description":"Frontend steps (aka, Screens) for this process.","items":{"$ref":"#/components/schemas/FrontendStep"}},"hasPermission":{"type":"boolean","description":"Boolean to indicate if the user has permission for the process.","nullable":true},"helpContents":{"type":"object","description":"Help entries by slot, filtered for the current session.","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/HelpContentV1"}}},"icon":{"description":"Icon to display for the process.","$ref":"#/components/schemas/Icon"},"iconName":{"type":"string","description":"Material UI icon name (web); prefer iconSemanticName"},"iconSemanticName":{"type":"string","description":"Client-neutral kebab-case icon token; null when unmapped."},"isHidden":{"type":"boolean","description":"Boolean indicator of whether the process should be shown to users or not","nullable":true},"label":{"type":"string","description":"User-facing name for this process"},"maxInputRecords":{"type":"number","description":"Most input records the process runs with, when it has a maximum."},"minInputRecords":{"type":"number","description":"Fewest input records the process runs with (for processes on a table's records)."},"name":{"type":"string","description":"Unique name for this process within the QQQ Instance"},"stepFlow":{"type":"string","description":"Indicator of the Step Flow used by the process. Possible values are: LINEAR, STATE_MACHINE."},"tableName":{"type":"string","description":"If this process is associated with a table, the table name is given here"}}},"ProcessMetaDataAdjustment":{"type":"object","properties":{"updatedFields":{"type":"object","description":"Fields whose meta-data has changed. e.g., changing a label, or required status, or inline-possible-values.","additionalProperties":{"$ref":"#/components/schemas/FieldMetaData"}},"updatedFrontendStepList":{"type":"array","description":"In case the backend has changed the list of frontend steps, it will be set in this field.","items":{"$ref":"#/components/schemas/FrontendStep"}}}},"ProcessMetaDataLight":{"type":"object","properties":{"durableJobAlways":{"type":"boolean","description":"True when the process always runs as a durable background job (too large to run while the user waits).","nullable":true},"durableJobEligible":{"type":"boolean","description":"True when the process can run as a durable background job (POST /processes/{processName}/jobs): clients may offer \"Run in background\".","nullable":true},"hasPermission":{"type":"boolean","description":"Boolean to indicate if the user has permission for the process.","nullable":true},"helpContents":{"type":"object","description":"Help entries by slot, filtered for the current session.","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/HelpContentV1"}}},"icon":{"description":"Icon to display for the process.","$ref":"#/components/schemas/Icon"},"iconName":{"type":"string","description":"Material UI icon name (web); prefer iconSemanticName"},"iconSemanticName":{"type":"string","description":"Client-neutral kebab-case icon token; null when unmapped."},"isHidden":{"type":"boolean","description":"Boolean indicator of whether the process should be shown to users or not","nullable":true},"label":{"type":"string","description":"User-facing name for this process"},"maxInputRecords":{"type":"number","description":"Most input records the process runs with, when it has a maximum."},"minInputRecords":{"type":"number","description":"Fewest input records the process runs with (for processes on a table's records)."},"name":{"type":"string","description":"Unique name for this process within the QQQ Instance"},"stepFlow":{"type":"string","description":"Indicator of the Step Flow used by the process. Possible values are: LINEAR, STATE_MACHINE."},"tableName":{"type":"string","description":"If this process is associated with a table, the table name is given here"}}},"ProcessMetaDataResponseV1":{"type":"object","properties":{"durableJobAlways":{"type":"boolean","description":"True when the process always runs as a durable background job (too large to run while the user waits).","nullable":true},"durableJobEligible":{"type":"boolean","description":"True when the process can run as a durable background job (POST /processes/{processName}/jobs): clients may offer \"Run in background\".","nullable":true},"frontendSteps":{"type":"array","description":"Frontend steps (aka, Screens) for this process.","items":{"$ref":"#/components/schemas/FrontendStep"}},"hasPermission":{"type":"boolean","description":"Boolean to indicate if the user has permission for the process.","nullable":true},"helpContents":{"type":"object","description":"Help entries by slot, filtered for the current session.","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/HelpContentV1"}}},"icon":{"type":"object","description":"Icon to display for the process.","properties":{"color":{"type":"string","description":"A color code to use for displaying the icon"},"name":{"type":"string","description":"Material UI icon name (web); prefer semanticName"},"path":{"type":"string","description":"A path to an image file that can be requested from the server, to serve as the icon image instead of a material UI icon."},"semanticName":{"type":"string","description":"Client-neutral kebab-case icon token; null when unmapped."}}},"iconName":{"type":"string","description":"Material UI icon name (web); prefer iconSemanticName"},"iconSemanticName":{"type":"string","description":"Client-neutral kebab-case icon token; null when unmapped."},"isHidden":{"type":"boolean","description":"Boolean indicator of whether the process should be shown to users or not","nullable":true},"label":{"type":"string","description":"User-facing name for this process"},"maxInputRecords":{"type":"number","description":"Most input records the process runs with, when it has a maximum."},"minInputRecords":{"type":"number","description":"Fewest input records the process runs with (for processes on a table's records)."},"name":{"type":"string","description":"Unique name for this process within the QQQ Instance"},"stepFlow":{"type":"string","description":"Indicator of the Step Flow used by the process. Possible values are: LINEAR, STATE_MACHINE."},"tableName":{"type":"string","description":"If this process is associated with a table, the table name is given here"}}},"ProcessRecordsResponseV1":{"type":"object","properties":{"records":{"type":"array","description":"List of records from the process state","items":{"$ref":"#/components/schemas/OutputRecord"}},"totalRecords":{"type":"number","description":"Total number of records in the process state (before pagination)"}}},"ProcessStepComplete":{"type":"object","description":"Data returned after the job is complete (whether it was synchronous, or asynchronous)","properties":{"backStep":{"type":"string","description":"Name of the step the process can go back to (restart at, by stepping with isStepBack=true), when the process declares one. Omitted otherwise."},"nextStep":{"type":"string","description":"Name of the next process step that needs to run (a frontend step). If there are no more steps in the process, this field will not be included. "},"oneTimeSecrets":{"type":"array","description":"Secrets shown once in synchronous init/step responses only. Never returned by status. Clients must not cache; response uses Cache-Control: no-store.","items":{"$ref":"#/components/schemas/PreferenceSecretV1"}},"processMetaDataAdjustment":{"type":"object","description":"Changes to be made to the process's metaData.","properties":{"updatedFields":{"type":"object","description":"Fields whose meta-data has changed. e.g., changing a label, or required status, or inline-possible-values.","additionalProperties":{"$ref":"#/components/schemas/FieldMetaData"}},"updatedFrontendStepList":{"type":"array","description":"In case the backend has changed the list of frontend steps, it will be set in this field.","items":{"type":"object","properties":{"backStepName":{"type":"string","description":"Name of the step a user can go back to from this step (step with isStepBack=true), when there is one."},"components":{"type":"array","description":"The components that make up this screen","items":{"$ref":"#/components/schemas/FrontendComponent"}},"formFields":{"type":"array","description":"Fields used as form fields (inputs) on this step/screen","items":{"$ref":"#/components/schemas/FieldMetaData"}},"format":{"type":"string","description":"An optional indicator of the screen format preferred by the application to be used for this screen. Different frontends may support different formats, and implement them differently."},"helpContents":{"type":"array","description":"Help content shown on the step/screen.","items":{"$ref":"#/components/schemas/HelpContentV1"}},"label":{"type":"string","description":"The user-facing name for this step"},"name":{"type":"string","description":"The unique name for this step within its process"},"recordListFields":{"type":"array","description":"Fields used in record-lists shown on the step/screen.","items":{"$ref":"#/components/schemas/FieldMetaData"}},"viewFields":{"type":"array","description":"Fields used as view-only fields on this step/screen","items":{"$ref":"#/components/schemas/FieldMetaData"}}}}}}},"processUUID":{"type":"string","description":"Unique identifier for a running instance the process."},"type":{"type":"string","description":"What kind of response has been received. Determines what additional fields will be set."},"values":{"type":"object","description":"Current values for fields used by the process.Keys are Strings, values can be any type, as determined by the application & process."}}},"ProcessStepError":{"type":"object","description":"In case an error is thrown in the backend job.","properties":{"error":{"type":"string","description":"Exception message, in case the process step threw an error."},"processUUID":{"type":"string","description":"Unique identifier for a running instance the process."},"type":{"type":"string","description":"What kind of response has been received. Determines what additional fields will be set."},"userFacingError":{"type":"string","description":"Optional user-facing exception message, in case the process step threw a user-facing error."}}},"ProcessStepJobStarted":{"type":"object","description":"In case the backend needs more time, this is a UUID of the background job that has been started.","properties":{"jobUUID":{"type":"string","description":"Unique identifier for a running step of the process. Must be passed into `status` check calls."},"processUUID":{"type":"string","description":"Unique identifier for a running instance the process."},"type":{"type":"string","description":"What kind of response has been received. Determines what additional fields will be set."}}},"ProcessStepResponseV1":{"oneOf":[{"type":"object","description":"Data returned after the job is complete (whether it was synchronous, or asynchronous)","properties":{"backStep":{"type":"string","description":"Name of the step the process can go back to (restart at, by stepping with isStepBack=true), when the process declares one. Omitted otherwise."},"nextStep":{"type":"string","description":"Name of the next process step that needs to run (a frontend step). If there are no more steps in the process, this field will not be included. "},"oneTimeSecrets":{"type":"array","description":"Secrets shown once in synchronous init/step responses only. Never returned by status. Clients must not cache; response uses Cache-Control: no-store.","items":{"$ref":"#/components/schemas/PreferenceSecretV1"}},"processMetaDataAdjustment":{"type":"object","description":"Changes to be made to the process's metaData.","properties":{"updatedFields":{"type":"object","description":"Fields whose meta-data has changed. e.g., changing a label, or required status, or inline-possible-values.","additionalProperties":{"$ref":"#/components/schemas/FieldMetaData"}},"updatedFrontendStepList":{"type":"array","description":"In case the backend has changed the list of frontend steps, it will be set in this field.","items":{"type":"object","properties":{"backStepName":{"type":"string","description":"Name of the step a user can go back to from this step (step with isStepBack=true), when there is one."},"components":{"type":"array","description":"The components that make up this screen","items":{"$ref":"#/components/schemas/FrontendComponent"}},"formFields":{"type":"array","description":"Fields used as form fields (inputs) on this step/screen","items":{"$ref":"#/components/schemas/FieldMetaData"}},"format":{"type":"string","description":"An optional indicator of the screen format preferred by the application to be used for this screen. Different frontends may support different formats, and implement them differently."},"helpContents":{"type":"array","description":"Help content shown on the step/screen.","items":{"$ref":"#/components/schemas/HelpContentV1"}},"label":{"type":"string","description":"The user-facing name for this step"},"name":{"type":"string","description":"The unique name for this step within its process"},"recordListFields":{"type":"array","description":"Fields used in record-lists shown on the step/screen.","items":{"$ref":"#/components/schemas/FieldMetaData"}},"viewFields":{"type":"array","description":"Fields used as view-only fields on this step/screen","items":{"$ref":"#/components/schemas/FieldMetaData"}}}}}}},"processUUID":{"type":"string","description":"Unique identifier for a running instance the process."},"type":{"type":"string","description":"What kind of response has been received. Determines what additional fields will be set."},"values":{"type":"object","description":"Current values for fields used by the process.Keys are Strings, values can be any type, as determined by the application & process."}}},{"type":"object","description":"In case the backend needs more time, this is a UUID of the background job that has been started.","properties":{"jobUUID":{"type":"string","description":"Unique identifier for a running step of the process. Must be passed into `status` check calls."},"processUUID":{"type":"string","description":"Unique identifier for a running instance the process."},"type":{"type":"string","description":"What kind of response has been received. Determines what additional fields will be set."}}},{"type":"object","description":"Response to a status check for a backgrounded job.","properties":{"current":{"type":"number","description":"Optional indicator of progress (e.g., `current` of `total`, as in (`1 of 10`)."},"logTail":{"type":"array","items":{"$ref":"#/components/schemas/JobLogLineV1"}},"message":{"type":"string","description":"Status message regarding the running process step."},"processUUID":{"type":"string","description":"Unique identifier for a running instance the process."},"progress":{"type":"object","properties":{"bytesDone":{"type":"number"},"bytesTotal":{"type":"number"},"currentPhase":{"type":"string"},"done":{"type":"number"},"etaSeconds":{"type":"number"},"message":{"type":"string"},"percent":{"type":"number"},"phases":{"type":"array","items":{"$ref":"#/components/schemas/JobPhaseV1"}},"total":{"type":"number"},"unitLabel":{"type":"string"},"updatedAt":{"type":"string"}}},"total":{"type":"number","description":"Optional indicator of progress (e.g., `current` of `total`, as in (`1 of 10`)."},"type":{"type":"string","description":"What kind of response has been received. Determines what additional fields will be set."}}},{"type":"object","description":"In case an error is thrown in the backend job.","properties":{"error":{"type":"string","description":"Exception message, in case the process step threw an error."},"processUUID":{"type":"string","description":"Unique identifier for a running instance the process."},"type":{"type":"string","description":"What kind of response has been received. Determines what additional fields will be set."},"userFacingError":{"type":"string","description":"Optional user-facing exception message, in case the process step threw a user-facing error."}}}]},"ProcessStepRunning":{"type":"object","description":"Response to a status check for a backgrounded job.","properties":{"current":{"type":"number","description":"Optional indicator of progress (e.g., `current` of `total`, as in (`1 of 10`)."},"logTail":{"type":"array","items":{"$ref":"#/components/schemas/JobLogLineV1"}},"message":{"type":"string","description":"Status message regarding the running process step."},"processUUID":{"type":"string","description":"Unique identifier for a running instance the process."},"progress":{"type":"object","properties":{"bytesDone":{"type":"number"},"bytesTotal":{"type":"number"},"currentPhase":{"type":"string"},"done":{"type":"number"},"etaSeconds":{"type":"number"},"message":{"type":"string"},"percent":{"type":"number"},"phases":{"type":"array","items":{"$ref":"#/components/schemas/JobPhaseV1"}},"total":{"type":"number"},"unitLabel":{"type":"string"},"updatedAt":{"type":"string"}}},"total":{"type":"number","description":"Optional indicator of progress (e.g., `current` of `total`, as in (`1 of 10`)."},"type":{"type":"string","description":"What kind of response has been received. Determines what additional fields will be set."}}},"PublicBranding":{"type":"object","properties":{"accentColor":{"type":"string","description":"Primary accent color, as a CSS color value."},"accentColorLight":{"type":"string","description":"Light variant of the accent color, as a CSS color value."},"appName":{"type":"string","description":"Name of this application, for display to users."},"companyName":{"type":"string","description":"Name of the company that operates this application."},"icon":{"type":"string","description":"Path or URL of the application's small icon image."},"logo":{"type":"string","description":"Path or URL of the application's logo image."}}},"QueryFilter":{"type":"object","properties":{"booleanOperator":{"type":"string","description":"Boolean operator to apply between criteria","enum":["AND","OR"]},"criteria":{"type":"array","description":"Field level criteria that make up the query filter","items":{"$ref":"#/components/schemas/FilterCriteria"}},"limit":{"type":"number","description":"Maximum number of results to return."},"orderBys":{"type":"array","description":"How the query's results should be ordered (sorted).","items":{"$ref":"#/components/schemas/OrderBy"}},"skip":{"type":"number","description":"Records to skip (e.g., to implement pagination)"}}},"QueryJoin":{"type":"object","properties":{"alias":{"type":"string","description":"Alias to apply to this table in the join query"},"baseTableOrAlias":{"type":"string","description":"Base table (or an alias) that this QueryJoin is joined against"},"joinName":{"type":"string","description":"Name of a join to use in case the baseTable and joinTable have more than one"},"joinTable":{"type":"string","description":"Table being joined into the query by this QueryJoin"},"select":{"type":"boolean","description":"Whether or not to select values from the join table","nullable":true},"type":{"type":"string","description":"Type of join being performed (SQL semantics)","enum":["INNER","LEFT","RIGHT","FULL"]}}},"RealtimeChannelRevokedEventV1":{"type":"object","properties":{"channel":{"type":"string"}}},"RealtimeEventV1":{"type":"object","properties":{"channel":{"type":"string"},"data":{"type":"object","description":"dataByType: hello -> RealtimeHelloEventV1; job.progress -> RealtimeJobProgressEventV1; record.changed -> RealtimeRecordChangedEventV1; record.deleted -> RealtimeRecordDeletedEventV1; table.changed -> RealtimeTableChangedEventV1; metadata.changed -> RealtimeMetaDataChangedEventV1; session-ended -> RealtimeSessionEndedEventV1; resync -> RealtimeResyncEventV1; channel-revoked -> RealtimeChannelRevokedEventV1. Selected by the envelope's event; data has no discriminator. All properties are optional; QBits may publish additional event-specific data.","properties":{"bytesDone":{"type":"number"},"bytesTotal":{"type":"number"},"changedBy":{"type":"string"},"channel":{"type":"string"},"chunksDone":{"type":"number"},"chunksTotal":{"type":"number"},"connectionId":{"type":"string"},"currentPhase":{"type":"string"},"etaSeconds":{"type":"number"},"fields":{"type":"array","items":{"type":"string"}},"generation":{"type":"integer"},"heartbeatSeconds":{"type":"integer"},"jobId":{"type":"number"},"logSeq":{"type":"number"},"message":{"type":"string"},"metaDataGeneration":{"type":"integer"},"percent":{"type":"number"},"pk":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}],"nullable":true},"rowsDone":{"type":"number"},"rowsFailed":{"type":"number"},"rowsPerSecond":{"type":"number"},"rowsTotal":{"type":"number"},"status":{"type":"string"},"table":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}],"nullable":true}}},"event":{"type":"string"}}},"RealtimeHelloEventV1":{"type":"object","properties":{"connectionId":{"type":"string"},"heartbeatSeconds":{"type":"integer"},"metaDataGeneration":{"type":"integer"}}},"RealtimeJobProgressEventV1":{"type":"object","properties":{"bytesDone":{"type":"number"},"bytesTotal":{"type":"number"},"chunksDone":{"type":"number"},"chunksTotal":{"type":"number"},"currentPhase":{"type":"string"},"etaSeconds":{"type":"number"},"jobId":{"type":"number"},"logSeq":{"type":"number"},"message":{"type":"string"},"percent":{"type":"number"},"rowsDone":{"type":"number"},"rowsFailed":{"type":"number"},"rowsPerSecond":{"type":"number"},"rowsTotal":{"type":"number"},"status":{"type":"string"}}},"RealtimeMetaDataChangedEventV1":{"type":"object","properties":{"generation":{"type":"integer"}}},"RealtimeRecordChangedEventV1":{"type":"object","properties":{"changedBy":{"type":"string"},"fields":{"type":"array","items":{"type":"string"}},"pk":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}],"nullable":true},"table":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}],"nullable":true}}},"RealtimeRecordDeletedEventV1":{"type":"object","properties":{"pk":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}],"nullable":true},"table":{"type":"string"}}},"RealtimeResyncEventV1":{"type":"object"},"RealtimeSessionEndedEventV1":{"type":"object"},"RealtimeSubscriptionRequestV1":{"type":"object","properties":{"add":{"type":"array","items":{"type":"string"}},"connectionId":{"type":"string"},"remove":{"type":"array","items":{"type":"string"}}}},"RealtimeSubscriptionResponseV1":{"type":"object","properties":{"active":{"type":"array","items":{"type":"string"}},"refused":{"type":"array","items":{"type":"string"}}}},"RealtimeTableChangedEventV1":{"type":"object","properties":{"table":{"type":"string"}}},"RecordAssociatedScriptLogsResponseV1":{"type":"object","properties":{"scriptLogRecords":{"type":"array","description":"The script revision's logs (scriptLog records, up to 100), newest (highest id) first. Each record's values include `scriptLogLine`: the log's lines, as a list of records (each with its own `values`, e.g., `text`).","items":{"$ref":"#/components/schemas/OutputRecord"}}}},"RecordAssociatedScriptStoreResponseV1":{"type":"object","properties":{"scriptId":{"type":"number","description":"Id of the script (which is inserted, and referenced from the record, if the record did not yet reference one)."},"scriptName":{"type":"string","description":"Name of the script."},"scriptRevisionId":{"type":"number","description":"Id of the new script revision."},"scriptRevisionSequenceNo":{"type":"number","description":"Sequence number of the new revision within the script (1 for its first revision)."}}},"RecordConflictV1":{"type":"object","properties":{"changedFields":{"type":"array","items":{"type":"string"}},"currentVersion":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}],"nullable":true},"modifiedAt":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}],"nullable":true},"modifiedByUserId":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}],"nullable":true}}},"RecordDeveloperModeAssociatedScript":{"type":"object","properties":{"associatedScript":{"description":"Definition of the associated script, from the table's meta-data.","$ref":"#/components/schemas/AssociatedScriptMetaData"},"script":{"description":"The script record that the record references. Omitted if the record does not reference an existing script.","$ref":"#/components/schemas/OutputRecord"},"scriptRevisions":{"type":"array","description":"The script's revisions (scriptRevision records), newest (highest id) first. Present (possibly empty) when script is.","items":{"$ref":"#/components/schemas/OutputRecord"}},"scriptType":{"description":"The scriptType record of the associated script. Omitted if there is no such record.","$ref":"#/components/schemas/OutputRecord"},"testInputFields":{"type":"array","description":"Input fields for testing the script. Present (possibly empty) when the associated script has a script tester.","items":{"$ref":"#/components/schemas/FieldMetaData"}},"testOutputFields":{"type":"array","description":"Output fields from testing the script. Present (possibly empty) when the associated script has a script tester.","items":{"$ref":"#/components/schemas/FieldMetaData"}}}},"RecordDeveloperModeResponseV1":{"type":"object","properties":{"associatedScripts":{"type":"array","description":"Each of the table's associated scripts, with the script the record references (if any). Empty when the table has no associated scripts (or the instance has no script tables).","items":{"$ref":"#/components/schemas/RecordDeveloperModeAssociatedScript"}},"record":{"type":"object","description":"The record, with display values (and possible values translated).","properties":{"associatedRecords":{"type":"object","description":"Records associated with this record, keyed by association name. Each value is a list of records with the same shape as this one. Only present when associations were requested or written.","additionalProperties":{"type":"array"}},"displayValues":{"type":"object","description":"Formatted string versions of the values that make up the record. Keys are Strings, which match the table's field names. Values are all Strings."},"errors":{"type":"array","description":"Messages for errors on this record (for example on an associated record that could not be written). Omitted when there are none.","items":{"type":"string"}},"recordLabel":{"type":"string","description":"Label to identify the record to a user."},"tableName":{"type":"string","description":"Name of the table that the record is from."},"values":{"type":"object","description":"Raw values that make up the record. Keys are Strings, which match the table's field names. Values can be any type, as per the table's fields. Single-record responses (get, insert, update) include fields whose value is null; query results omit them."},"warnings":{"type":"array","description":"Messages for warnings on this record. Omitted when there are none.","items":{"type":"string"}}}}}},"RecordDeveloperPanelsResponseV1":{"type":"object","properties":{"panels":{"type":"array","description":"The panels that the instance's developer panel providers contribute for this record, sorted by order then title. Each panel has an id, title, order, optional icon, description and status badge (statusLabel, statusTone: INFO, SUCCESS, WARNING or ERROR), and either an error message (when its provider failed) or a list of blocks. Each block has a type and a label; KEY_VALUES blocks use items (label, value, monospace, href), TEXT blocks use text and tone, CODE blocks use language and code, TABLE blocks use columns and rows (lists of display strings), LINKS blocks use links (label, href, description, external) and ACTIONS blocks use actions (label, processName, tableName, includeRecordId, description). Hrefs are app-relative (e.g., /app/table/1) or absolute.","items":{"type":"object","properties":{"blocks":{"type":"array"},"description":{"type":"string"},"error":{"type":"string"},"icon":{"type":"string"},"id":{"type":"string"},"order":{"type":"number"},"statusLabel":{"type":"string"},"statusTone":{"type":"string","enum":["INFO","SUCCESS","WARNING","ERROR"]},"title":{"type":"string"}}}}}},"RecordFeatureSummaryV1":{"type":"object","properties":{"tableName":{"type":"string"},"primaryKey":{"type":"string"},"features":{"type":"array","items":{"type":"string","enum":["ATTACHMENTS","TAGS","CUSTOM_FIELDS","COMMENTS","PRESENCE","SHARING","FAVORITES","FOLLOW","TIMELINE","RECENTS","TASKS","ASSIGNMENT"]}},"capabilities":{"type":"object","additionalProperties":{"type":"boolean"}},"isFavorite":{"type":"boolean","nullable":true},"isFollowing":{"type":"boolean","nullable":true},"counts":{"type":"object","additionalProperties":{"type":"integer"}},"owner":{"type":"string","nullable":true},"assignee":{"type":"string","nullable":true},"presence":{"type":"array","items":{"type":"object","description":"Provider-defined presence entry: user identity and activity values.","additionalProperties":{}},"nullable":true},"extensions":{"type":"object","additionalProperties":{"type":"object","description":"Provider-specific record feature extension values.","additionalProperties":true}}}},"RecordFeaturesV1":{"type":"object","properties":{"capabilities":{"type":"object","additionalProperties":{"type":"boolean"}},"features":{"type":"array","items":{"type":"string","enum":["ATTACHMENTS","TAGS","CUSTOM_FIELDS","COMMENTS","PRESENCE","SHARING","FAVORITES","FOLLOW","TIMELINE","RECENTS","TASKS","ASSIGNMENT"]}},"ownership":{"type":"object","properties":{"assigneeFieldName":{"type":"string"},"ownerFieldName":{"type":"string"}}},"settings":{"type":"object","additionalProperties":{"type":"object","description":"Feature-provider settings, keyed by provider-defined setting names.","additionalProperties":true}}}},"RecordSearchDetailV1":{"type":"object","properties":{"displayValue":{"type":"string","description":"Display value of the field."},"fieldLabel":{"type":"string","description":"User-facing label of the field."},"fieldName":{"type":"string","description":"Name of the field."}}},"RecordSearchHighlightMatchV1":{"type":"object","properties":{"end":{"type":"number","description":"Offset just after the last matched character (exclusive)."},"start":{"type":"number","description":"Offset of the first matched character in the highlight text."}}},"RecordSearchHighlightV1":{"type":"object","properties":{"fieldLabel":{"type":"string","description":"User-facing label of the field."},"fieldName":{"type":"string","description":"Name of the field the snippet is from."},"matches":{"type":"array","description":"Matched spans in the text: sorted, non-overlapping character offsets (start inclusive, end exclusive).","items":{"$ref":"#/components/schemas/RecordSearchHighlightMatchV1"}},"text":{"type":"string","description":"Plain-text snippet of the field value (never markup; an ellipsis marks trimmed ends)."}}},"RecordSearchProviderStatusV1":{"type":"object","properties":{"failureClass":{"type":"string","description":"When the provider failed: the simple class name of the root cause (e.g., ConnectException)."},"message":{"type":"string","description":"When the provider failed with a user-facing error: its message (one line)."},"status":{"type":"string","description":"OK: the provider searched the tables it claimed. FAILED: it failed, and those tables were searched with the default search. NONE: there is no provider, or it claimed none of the searched tables.","enum":["OK","FAILED","NONE"]}}},"RecordSearchResponseV1":{"type":"object","properties":{"provider":{"type":"object","description":"How the instance's record search provider fared: when its status is FAILED, the tables it claimed were searched with the default search instead (their source is FALLBACK).","properties":{"failureClass":{"type":"string","description":"When the provider failed: the simple class name of the root cause (e.g., ConnectException)."},"message":{"type":"string","description":"When the provider failed with a user-facing error: its message (one line)."},"status":{"type":"string","description":"OK: the provider searched the tables it claimed. FAILED: it failed, and those tables were searched with the default search. NONE: there is no provider, or it claimed none of the searched tables.","enum":["OK","FAILED","NONE"]}}},"results":{"type":"array","description":"Records whose search fields match the search term, grouped by table (in instance order) and, within each table, in the requested order (RELEVANCE: the search provider's order, or by primary key for the default search; RECENT: most recently modified first).","items":{"$ref":"#/components/schemas/RecordSearchResultV1"}},"tables":{"type":"array","description":"A summary of each searched table, in the order of the results: how many results it returned, whether it has more, and what searched it.","items":{"$ref":"#/components/schemas/RecordSearchTableSummaryV1"}}}},"RecordSearchResultV1":{"type":"object","properties":{"details":{"type":"array","description":"Other search field values (not in the record label, and not highlighted) to show under the record label.","items":{"$ref":"#/components/schemas/RecordSearchDetailV1"}},"highlights":{"type":"array","description":"Plain-text snippets of the fields (other than those in the record label) that match the search term, with the matched spans.","items":{"$ref":"#/components/schemas/RecordSearchHighlightV1"}},"recordId":{"type":"string","description":"Primary key of the record, as a string."},"recordLabel":{"type":"string","description":"Label to identify the record to a user."},"score":{"type":"number","description":"Relevance from the record search provider (higher is better); absent for the default search."},"tableLabel":{"type":"string","description":"User-facing label of the table that the record is from."},"tableName":{"type":"string","description":"Name of the table that the record is from."},"updatedAt":{"type":"string","description":"When the record was last modified (ISO-8601 instant), when its table has a last-modified field the user may see."}}},"RecordSearchTableSummaryV1":{"type":"object","properties":{"hasMore":{"type":"boolean","description":"Whether the table has more matches past these results (request them with offset).","nullable":true},"resultCount":{"type":"number","description":"Number of results returned from the table."},"source":{"type":"string","description":"What searched the table: the record search PROVIDER, the DEFAULT search, or the default search as a FALLBACK because the provider failed.","enum":["PROVIDER","DEFAULT","FALLBACK"]},"tableLabel":{"type":"string","description":"User-facing label of the table."},"tableName":{"type":"string","description":"Name of the table."},"totalCount":{"type":"number","description":"Approximate total number of matches in the table, when the search knows it (records the user may not read can make it high)."}}},"RelatedRecordPicker":{"type":"object","properties":{"associationName":{"type":"string","description":"The association whose rows the picker adds (MULTI_CHILD, LINK)"},"canAddChildren":{"type":"boolean","description":"Whether the user may add child or join rows (prepare and add routes)","nullable":true},"canCreateTarget":{"type":"boolean","description":"Whether to offer quick-create of a target record (insert route of targetTableName)","nullable":true},"canRemoveChildren":{"type":"boolean","description":"Whether the user may unlink (remove route; LINK only)","nullable":true},"childTableName":{"type":"string","description":"The child or join table new rows go into (MULTI_CHILD, LINK)"},"childTargetFieldName":{"type":"string","description":"The child table's field that holds the picked record's key (MULTI_CHILD, LINK)"},"columns":{"type":"array","description":"Target fields to show as result columns","items":{"type":"string"}},"defaultFilter":{"description":"Initial, user-editable filter; the query route returns it resolved as resolvedDefaultFilter","$ref":"#/components/schemas/QueryFilter"},"fieldName":{"type":"string","description":"The foreign-key field the picker sets (SINGLE)"},"filter":{"description":"Filter the server always applies to the picker's queries (may contain ${input.fieldName} variables, read from the parent record)","$ref":"#/components/schemas/QueryFilter"},"label":{"type":"string","description":"Dialog title, and the label of the button that opens it"},"maxSelections":{"type":"number","description":"Most records one add or link may pick (MULTI_CHILD, LINK)"},"mode":{"type":"string","description":"SINGLE: choose one record for fieldName. MULTI_CHILD: add child rows through associationName, after a review of reviewFieldNames. LINK: link and unlink through associationName (a join table)."},"name":{"type":"string","description":"Picker name; the {pickerName} path segment of the relatedRecordPicker routes"},"previewFields":{"type":"array","description":"Target fields to show for the highlighted record","items":{"type":"string"}},"reviewFieldNames":{"type":"array","description":"Child fields the user fills per picked record before saving (MULTI_CHILD); empty means no review step","items":{"type":"string"}},"targetTableName":{"type":"string","description":"The table records are picked from (read its metadata for fields, sections and quickCreateSectionName)"},"thumbnailField":{"type":"string","description":"Target field holding an image URL, for thumbnails"}}},"RelatedRecordPickerAddResponseV1":{"type":"object","properties":{"records":{"type":"array","description":"The inserted child or join rows","items":{"$ref":"#/components/schemas/OutputRecord"}},"warnings":{"type":"array","description":"Warnings from the inserts, if any","items":{"type":"string"}}}},"RelatedRecordPickerPrepareResponseV1":{"type":"object","properties":{"records":{"type":"array","description":"One unsaved child row per target id, in request order, with defaults, values copied from the target, and the parent and target keys (whose display value is the target's label)","items":{"$ref":"#/components/schemas/OutputRecord"}},"reviewFieldNames":{"type":"array","description":"Child fields for the user to review per row before the add route; empty means add without a review","items":{"type":"string"}}}},"RelatedRecordPickerQueryResponseV1":{"type":"object","properties":{"hasMore":{"type":"boolean","description":"Whether more records follow (request the next page with skip); there is no count","nullable":true},"linkedIds":{"type":"array","description":"Ids (as strings) of the returned records the parent already has a child or join row for (MULTI_CHILD, LINK with primaryKey)","items":{"type":"string"}},"records":{"type":"array","description":"One page of target records (values and display values), in order","items":{"$ref":"#/components/schemas/OutputRecord"}},"resolvedDefaultFilter":{"type":"object","description":"The picker's defaultFilter with its variables resolved, to start the dialog's filter from (first page only)","properties":{"booleanOperator":{"type":"string","description":"Boolean operator to apply between criteria","enum":["AND","OR"]},"criteria":{"type":"array","description":"Field level criteria that make up the query filter","items":{"$ref":"#/components/schemas/FilterCriteria"}},"limit":{"type":"number","description":"Maximum number of results to return."},"orderBys":{"type":"array","description":"How the query's results should be ordered (sorted).","items":{"$ref":"#/components/schemas/OrderBy"}},"skip":{"type":"number","description":"Records to skip (e.g., to implement pagination)"}}}}},"RelatedRecordPickerRemoveResponseV1":{"type":"object","properties":{"deletedCount":{"type":"number","description":"How many join rows were deleted"}}},"ReportMetaData":{"type":"object","properties":{"hasPermission":{"type":"boolean","description":"Whether the user may run the report."},"helpContents":{"type":"object","description":"Help entries by slot, filtered for the current session.","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/HelpContentV1"}}},"iconName":{"type":"string","description":"Material UI icon name (web); prefer iconSemanticName"},"iconSemanticName":{"type":"string","description":"Client-neutral kebab-case icon token; null when unmapped."},"label":{"type":"string","description":"User-facing name for this report."},"name":{"type":"string","description":"Unique name for this report within the QQQ Instance."},"processName":{"type":"string","description":"Process that runs this report, when it has one; otherwise it runs from GET /reports/{reportName}."}}},"SavedViewsCapabilityV1":{"type":"object","properties":{"available":{"type":"boolean","description":"True when the user may list saved views (queryProcessName can run).","nullable":true},"deleteProcessName":{"type":"string","description":"Deletes a view; absent when the user may not delete views."},"queryProcessName":{"type":"string","description":"Lists the views (input tableName; output savedViewList)."},"storeProcessName":{"type":"string","description":"Stores (inserts or updates) a view; absent when the user may not store views."}}},"SharingCapabilityV1":{"type":"object","properties":{"available":{"type":"boolean","description":"True when the table is shareable and the user may list shares.","nullable":true},"deleteProcessName":{"type":"string","description":"Removes a share."},"editProcessName":{"type":"string","description":"Changes a share's scope."},"insertProcessName":{"type":"string","description":"Adds a share (the record owner only; the server checks)."},"listProcessName":{"type":"string","description":"Lists a record's shares."}}},"SupplementalInstanceMetaData":{"type":"object","properties":{"assistant":{"type":"object","description":"Present (an object) when the instance has the assistant QBit's `assistant` supplemental meta-data - that is, when the assistant is installed and enabled, so a frontend may probe its routes. Always has `available: true`, plus the strings, numbers and booleans the QBit publishes for frontends.","additionalProperties":true},"materialDashboard":{"description":"Use uiSettings; kept for Next UI until it migrates","deprecated":true,"$ref":"#/components/schemas/MaterialDashboardInstanceSettings"},"materialDashboardTheme":{"type":"object","description":"Use uiSettings; kept for Next UI until it migrates. The application theme from the instance's MaterialDashboardThemeMetaData supplemental meta-data, when the instance defines it. Keys are MaterialDashboardThemeMetaData property names (for example primaryColor, fontFamily, typographyH1FontSize, borderRadiusGlobal, density, customCss, brandedHeaderEnabled, sidebarBackgroundColor, tableHeaderBackgroundColor); values are strings, numbers or booleans. An explicit allow-list of the theme's visual properties; properties without a value are omitted.","additionalProperties":true,"deprecated":true},"uiSettings":{"description":"Client-neutral process, query, record-view and theme settings.","$ref":"#/components/schemas/UiSettings"}}},"TableApiDocumentV1":{"type":"object","description":"An OpenAPI 3 document (the application API's own format, not part of this API's schema).","additionalProperties":true},"TableApiV1":{"type":"object","description":"An application API that exposes the table.","properties":{"name":{"type":"string","description":"The API's name (a stable key)."},"label":{"type":"string","description":"Label to show users."},"path":{"type":"string","description":"Root-relative base path of the API, e.g. `/api/`."},"currentVersion":{"type":"string","description":"The version the API calls current.","nullable":true},"versions":{"type":"array","description":"Every version the API serves.","items":{"$ref":"#/components/schemas/TableApiVersionV1"}}}},"TableApiVersionV1":{"type":"object","description":"One version of an API.","properties":{"version":{"type":"string","description":"The version, as it appears in the API's URLs."},"semanticVersion":{"type":"string","description":"Its semantic version, when the API declares one.","nullable":true},"tableSpecPath":{"type":"string","description":"Root-relative path of the table's OpenAPI document (JSON) in this version."}}},"TableApisResponseV1":{"type":"object","description":"The APIs that expose a table.","properties":{"apis":{"type":"array","description":"The APIs, by name.","items":{"$ref":"#/components/schemas/TableApiV1"}}}},"TableCapabilitiesV1":{"type":"object","properties":{"SAVED_VIEW_DELETE_PROCESS":{"type":"string"},"SAVED_VIEW_QUERY_PROCESS":{"type":"string"},"SAVED_VIEW_STORE_PROCESS":{"type":"string"},"audits":{"description":"Audit history of this table's records.","$ref":"#/components/schemas/AuditsCapabilityV1"},"bulkDelete":{"description":"Bulk delete of selected records.","$ref":"#/components/schemas/ProcessCapabilityV1"},"bulkEdit":{"description":"Bulk edit of selected records.","$ref":"#/components/schemas/ProcessCapabilityV1"},"bulkEditWithFile":{"description":"Bulk edit from a file.","$ref":"#/components/schemas/ProcessCapabilityV1"},"bulkInsert":{"description":"Bulk insert (load a file into the table).","$ref":"#/components/schemas/ProcessCapabilityV1"},"savedViews":{"description":"Saved views of this table.","$ref":"#/components/schemas/SavedViewsCapabilityV1"},"sharing":{"description":"Record sharing, for a shareable table.","$ref":"#/components/schemas/SharingCapabilityV1"}}},"TableCountResponseV1":{"type":"object","properties":{"count":{"type":"number","description":"Number (count) of records that satisfy the query request"},"distinctCount":{"type":"number","description":"Number (count) of distinct records that satisfy the query request. Only included if requested."}}},"TableDeleteResponseV1":{"type":"object","properties":{"deletedRecordCount":{"type":"number","description":"Number of records that were deleted"},"errors":{"type":"array","description":"Why records were not deleted (for example, a record that was not found). Omitted when every record was deleted.","items":{"type":"string"}}}},"TableGetResponseV1":{"type":"object","properties":{"record":{"type":"object","description":"The record that was fetched","properties":{"associatedRecords":{"type":"object","description":"Records associated with this record, keyed by association name. Each value is a list of records with the same shape as this one. Only present when associations were requested or written.","additionalProperties":{"type":"array"}},"displayValues":{"type":"object","description":"Formatted string versions of the values that make up the record. Keys are Strings, which match the table's field names. Values are all Strings."},"errors":{"type":"array","description":"Messages for errors on this record (for example on an associated record that could not be written). Omitted when there are none.","items":{"type":"string"}},"recordLabel":{"type":"string","description":"Label to identify the record to a user."},"tableName":{"type":"string","description":"Name of the table that the record is from."},"values":{"type":"object","description":"Raw values that make up the record. Keys are Strings, which match the table's field names. Values can be any type, as per the table's fields. Single-record responses (get, insert, update) include fields whose value is null; query results omit them."},"warnings":{"type":"array","description":"Messages for warnings on this record. Omitted when there are none.","items":{"type":"string"}}}}}},"TableInsertResponseV1":{"type":"object","properties":{"record":{"type":"object","description":"The record that was inserted","properties":{"associatedRecords":{"type":"object","description":"Records associated with this record, keyed by association name. Each value is a list of records with the same shape as this one. Only present when associations were requested or written.","additionalProperties":{"type":"array"}},"displayValues":{"type":"object","description":"Formatted string versions of the values that make up the record. Keys are Strings, which match the table's field names. Values are all Strings."},"errors":{"type":"array","description":"Messages for errors on this record (for example on an associated record that could not be written). Omitted when there are none.","items":{"type":"string"}},"recordLabel":{"type":"string","description":"Label to identify the record to a user."},"tableName":{"type":"string","description":"Name of the table that the record is from."},"values":{"type":"object","description":"Raw values that make up the record. Keys are Strings, which match the table's field names. Values can be any type, as per the table's fields. Single-record responses (get, insert, update) include fields whose value is null; query results omit them."},"warnings":{"type":"array","description":"Messages for warnings on this record. Omitted when there are none.","items":{"type":"string"}}}},"warnings":{"type":"array","description":"Any warnings that occurred during the insert","items":{"type":"string"}}}},"TableMenu":{"type":"object","properties":{"icon":{"description":"Icon of the menu's button.","$ref":"#/components/schemas/Icon"},"items":{"type":"array","description":"The menu's items, in order.","items":{"$ref":"#/components/schemas/TableMenuItem"}},"label":{"type":"string","description":"User-facing label of the menu's button."},"slot":{"type":"string","description":"Where the menu goes: VIEW_SCREEN_ACTIONS, VIEW_SCREEN_ADDITIONAL, QUERY_SCREEN_ACTIONS or QUERY_SCREEN_ADDITIONAL (or a slot the application defines)."}}},"TableMenuItem":{"type":"object","properties":{"icon":{"description":"Icon of the item, when it overrides the frontend's default.","$ref":"#/components/schemas/Icon"},"itemType":{"type":"string","description":"What the item is and how a frontend handles it: BUILT_IN (a standard action named by values.option, such as NEW, COPY, EDIT, DELETE, DEVELOPER_MODE, AUDIT, THIS_TABLE_PROCESS_LIST or ALL_TABLES_PROCESS_LIST), RUN_PROCESS (values.processName), DOWNLOAD_FILE (values.fieldName), SUB_MENU and SUB_LIST (values.items), or DIVIDER."},"label":{"type":"string","description":"User-facing label of the item, when it overrides the frontend's default."},"values":{"type":"object","description":"Item-type specific values: option for BUILT_IN, processName for RUN_PROCESS, fieldName for DOWNLOAD_FILE, and items (a list of menu items of this same shape) for SUB_MENU and SUB_LIST.","properties":{"fieldName":{"type":"string"},"items":{"type":"array","items":{"$ref":"#/components/schemas/TableMenuItem"}},"option":{"type":"string"},"processName":{"type":"string"}}}}},"TableMetaData":{"type":"object","properties":{"associations":{"type":"array","description":"Named record associations and their joins, without child record access","items":{"$ref":"#/components/schemas/Association"}},"builtInViews":{"type":"array","description":"Built-in views; evaluate their filters in the current session without persisting the resolved user id.","items":{"$ref":"#/components/schemas/BuiltInViewV1"}},"capabilities":{"type":"array","description":"List of strings describing actions that are supported by the backend application for the table.","items":{"type":"string"}},"clientCapabilities":{"description":"What a client may offer on this table beyond plain CRUD - saved views, audits, sharing and the bulk processes - with the process or table to use for each, for the current user. Clients use these instead of hard-coded process names. Since 1.6.0.","$ref":"#/components/schemas/TableCapabilitiesV1"},"deletePermission":{"type":"boolean","description":"Boolean to indicate if the user has delete permission for the table.","nullable":true},"editPermission":{"type":"boolean","description":"Boolean to indicate if the user has edit permission for the table.","nullable":true},"exposedJoins":{"type":"array","description":"Sections to organize fields on screens for this record","items":{"$ref":"#/components/schemas/ExposedJoin"}},"fields":{"type":"object","description":"Fields in this table","additionalProperties":{"$ref":"#/components/schemas/FieldMetaData"}},"hasRestrictedFields":{"type":"boolean","description":"True when any field has REVEALABLE, MASKED, or HIDDEN access for the current session.","nullable":true},"helpContents":{"type":"object","description":"Help Contents for this table.","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/HelpContentV1"}}},"icon":{"description":"Icon to display for the table","$ref":"#/components/schemas/Icon"},"insertPermission":{"type":"boolean","description":"Boolean to indicate if the user has insert permission for the table.","nullable":true},"isHidden":{"type":"boolean","description":"Boolean indicator of whether the table should be shown to users or not","nullable":true},"label":{"type":"string","description":"User-facing name for this table"},"menus":{"type":"array","description":"Menus the table defines for screen slots (for example the record view's VIEW_SCREEN_ACTIONS menu, which replaces the default actions menu, and VIEW_SCREEN_ADDITIONAL menus). Omitted when the table defines none.","items":{"$ref":"#/components/schemas/TableMenu"}},"metaDataGeneration":{"type":"number","description":"Runtime metadata generation; refetch metadata when this changes."},"name":{"type":"string","description":"Unique name for this table within the QQQ Instance"},"primaryKeyField":{"type":"string","description":"Name of the primary key field in this table"},"quickCreateSectionName":{"type":"string","description":"Name of the section whose editable fields a quick-create form shows (else the required, editable fields)"},"readPermission":{"type":"boolean","description":"Boolean to indicate if the user has read permission for the table.","nullable":true},"recordFeatures":{"description":"Enabled record collaboration features, public settings, and this session's table capabilities.","$ref":"#/components/schemas/RecordFeaturesV1"},"relatedRecordPickers":{"type":"array","description":"Related-record pickers of this table whose target the user may read (docs/RELATED-RECORD-PICKER.md)","items":{"$ref":"#/components/schemas/RelatedRecordPicker"}},"searchFields":{"type":"array","description":"Names of the fields that record search (POST /search) matches for this table. Only present when the table is searchable and the user has read permission for it.","items":{"type":"string"}},"sections":{"type":"array","description":"Sections to organize fields on screens for this record","items":{"$ref":"#/components/schemas/TableSection"}},"shareableTableMetaData":{"type":"object","description":"For tables that support the sharing feature, meta-data about the sharing setup.","properties":{"assetIdFieldName":{"type":"string"},"audiencePossibleValueSourceName":{"type":"string"},"audienceTypes":{"type":"object"},"audienceTypesPossibleValueSourceName":{"type":"string"},"scopeFieldName":{"type":"string"},"sharedRecordTableName":{"type":"string"},"thisTableOwnerIdFieldName":{"type":"string"}}},"supplementalMetaData":{"type":"object","description":"Additional meta data about the table, not necessarily known to QQQ."},"usesVariants":{"type":"boolean","description":"Whether or not this table's backend uses variants.","nullable":true},"variantTableLabel":{"type":"string","description":"If the table uses variants, this is the user-facing label for the table that supplies variants for this table."},"virtualFields":{"type":"object","description":"Virtual fields in this table","additionalProperties":{"$ref":"#/components/schemas/VirtualFieldMetaData"}}}},"TableMetaDataLight":{"type":"object","properties":{"capabilities":{"type":"array","description":"List of strings describing actions that are supported by the backend application for the table.","items":{"type":"string"}},"deletePermission":{"type":"boolean","description":"Boolean to indicate if the user has delete permission for the table.","nullable":true},"editPermission":{"type":"boolean","description":"Boolean to indicate if the user has edit permission for the table.","nullable":true},"helpContents":{"type":"object","description":"Help Contents for this table.","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/HelpContentV1"}}},"icon":{"description":"Icon to display for the table","$ref":"#/components/schemas/Icon"},"insertPermission":{"type":"boolean","description":"Boolean to indicate if the user has insert permission for the table.","nullable":true},"isHidden":{"type":"boolean","description":"Boolean indicator of whether the table should be shown to users or not","nullable":true},"label":{"type":"string","description":"User-facing name for this table"},"metaDataGeneration":{"type":"number","description":"Runtime metadata generation; refetch metadata when this changes."},"name":{"type":"string","description":"Unique name for this table within the QQQ Instance"},"readPermission":{"type":"boolean","description":"Boolean to indicate if the user has read permission for the table.","nullable":true},"recordFeatures":{"description":"Enabled record collaboration features, public settings, and this session's table capabilities.","$ref":"#/components/schemas/RecordFeaturesV1"},"searchFields":{"type":"array","description":"Names of the fields that record search (POST /search) matches for this table. Only present when the table is searchable and the user has read permission for it.","items":{"type":"string"}},"variantTableLabel":{"type":"string","description":"If the table uses variants, this is the user-facing label for the table that supplies variants for this table."}}},"TableMetaDataResponseV1":{"type":"object","properties":{"associations":{"type":"array","description":"Named record associations and their joins, without child record access","items":{"$ref":"#/components/schemas/Association"}},"builtInViews":{"type":"array","description":"Built-in views; evaluate their filters in the current session without persisting the resolved user id.","items":{"$ref":"#/components/schemas/BuiltInViewV1"}},"capabilities":{"type":"array","description":"List of strings describing actions that are supported by the backend application for the table.","items":{"type":"string"}},"clientCapabilities":{"type":"object","description":"What a client may offer on this table beyond plain CRUD - saved views, audits, sharing and the bulk processes - with the process or table to use for each, for the current user. Clients use these instead of hard-coded process names. Since 1.6.0.","properties":{"SAVED_VIEW_DELETE_PROCESS":{"type":"string"},"SAVED_VIEW_QUERY_PROCESS":{"type":"string"},"SAVED_VIEW_STORE_PROCESS":{"type":"string"},"audits":{"type":"object","description":"Audit history of this table's records.","properties":{"available":{"type":"boolean","description":"True when the user can read this table and its audits one of the two ways (the audit process enforces both). Independent of level: records of a table at level NONE can still have audits written explicitly.","nullable":true},"detailTableName":{"type":"string","description":"The audit detail table (field changes), joined to tableName."},"level":{"type":"string","description":"The table's audit level: NONE, RECORD or FIELD (informational: what is audited automatically)."},"processName":{"type":"string","description":"The process that returns a record's audits (inputs tableName, recordId); absent when the user may not run it."},"tableName":{"type":"string","description":"The audit table, when the user may query it directly."}}},"bulkDelete":{"type":"object","description":"Bulk delete of selected records.","properties":{"available":{"type":"boolean","description":"True when the process exists and the user may run it.","nullable":true},"processName":{"type":"string","description":"The process to run (present only when available)."}}},"bulkEdit":{"type":"object","description":"Bulk edit of selected records.","properties":{"available":{"type":"boolean","description":"True when the process exists and the user may run it.","nullable":true},"processName":{"type":"string","description":"The process to run (present only when available)."}}},"bulkEditWithFile":{"type":"object","description":"Bulk edit from a file.","properties":{"available":{"type":"boolean","description":"True when the process exists and the user may run it.","nullable":true},"processName":{"type":"string","description":"The process to run (present only when available)."}}},"bulkInsert":{"type":"object","description":"Bulk insert (load a file into the table).","properties":{"available":{"type":"boolean","description":"True when the process exists and the user may run it.","nullable":true},"processName":{"type":"string","description":"The process to run (present only when available)."}}},"savedViews":{"type":"object","description":"Saved views of this table.","properties":{"available":{"type":"boolean","description":"True when the user may list saved views (queryProcessName can run).","nullable":true},"deleteProcessName":{"type":"string","description":"Deletes a view; absent when the user may not delete views."},"queryProcessName":{"type":"string","description":"Lists the views (input tableName; output savedViewList)."},"storeProcessName":{"type":"string","description":"Stores (inserts or updates) a view; absent when the user may not store views."}}},"sharing":{"type":"object","description":"Record sharing, for a shareable table.","properties":{"available":{"type":"boolean","description":"True when the table is shareable and the user may list shares.","nullable":true},"deleteProcessName":{"type":"string","description":"Removes a share."},"editProcessName":{"type":"string","description":"Changes a share's scope."},"insertProcessName":{"type":"string","description":"Adds a share (the record owner only; the server checks)."},"listProcessName":{"type":"string","description":"Lists a record's shares."}}}}},"deletePermission":{"type":"boolean","description":"Boolean to indicate if the user has delete permission for the table.","nullable":true},"editPermission":{"type":"boolean","description":"Boolean to indicate if the user has edit permission for the table.","nullable":true},"exposedJoins":{"type":"array","description":"Sections to organize fields on screens for this record","items":{"$ref":"#/components/schemas/ExposedJoin"}},"fields":{"type":"object","description":"Fields in this table","additionalProperties":{"$ref":"#/components/schemas/FieldMetaData"}},"hasRestrictedFields":{"type":"boolean","description":"True when any field has REVEALABLE, MASKED, or HIDDEN access for the current session.","nullable":true},"helpContents":{"type":"object","description":"Help Contents for this table.","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/HelpContentV1"}}},"icon":{"type":"object","description":"Icon to display for the table","properties":{"color":{"type":"string","description":"A color code to use for displaying the icon"},"name":{"type":"string","description":"Material UI icon name (web); prefer semanticName"},"path":{"type":"string","description":"A path to an image file that can be requested from the server, to serve as the icon image instead of a material UI icon."},"semanticName":{"type":"string","description":"Client-neutral kebab-case icon token; null when unmapped."}}},"insertPermission":{"type":"boolean","description":"Boolean to indicate if the user has insert permission for the table.","nullable":true},"isHidden":{"type":"boolean","description":"Boolean indicator of whether the table should be shown to users or not","nullable":true},"label":{"type":"string","description":"User-facing name for this table"},"menus":{"type":"array","description":"Menus the table defines for screen slots (for example the record view's VIEW_SCREEN_ACTIONS menu, which replaces the default actions menu, and VIEW_SCREEN_ADDITIONAL menus). Omitted when the table defines none.","items":{"$ref":"#/components/schemas/TableMenu"}},"metaDataGeneration":{"type":"number","description":"Runtime metadata generation; refetch metadata when this changes."},"name":{"type":"string","description":"Unique name for this table within the QQQ Instance"},"primaryKeyField":{"type":"string","description":"Name of the primary key field in this table"},"quickCreateSectionName":{"type":"string","description":"Name of the section whose editable fields a quick-create form shows (else the required, editable fields)"},"readPermission":{"type":"boolean","description":"Boolean to indicate if the user has read permission for the table.","nullable":true},"recordFeatures":{"$ref":"#/components/schemas/RecordFeaturesV1"},"relatedRecordPickers":{"type":"array","description":"Related-record pickers of this table whose target the user may read (docs/RELATED-RECORD-PICKER.md)","items":{"$ref":"#/components/schemas/RelatedRecordPicker"}},"searchFields":{"type":"array","description":"Names of the fields that record search (POST /search) matches for this table. Only present when the table is searchable and the user has read permission for it.","items":{"type":"string"}},"sections":{"type":"array","description":"Sections to organize fields on screens for this record","items":{"$ref":"#/components/schemas/TableSection"}},"shareableTableMetaData":{"type":"object","description":"For tables that support the sharing feature, meta-data about the sharing setup.","properties":{"assetIdFieldName":{"type":"string"},"audiencePossibleValueSourceName":{"type":"string"},"audienceTypes":{"type":"object"},"audienceTypesPossibleValueSourceName":{"type":"string"},"scopeFieldName":{"type":"string"},"sharedRecordTableName":{"type":"string"},"thisTableOwnerIdFieldName":{"type":"string"}}},"supplementalMetaData":{"type":"object","description":"Additional meta data about the table, not necessarily known to QQQ."},"usesVariants":{"type":"boolean","description":"Whether or not this table's backend uses variants.","nullable":true},"variantTableLabel":{"type":"string","description":"If the table uses variants, this is the user-facing label for the table that supplies variants for this table."},"virtualFields":{"type":"object","description":"Virtual fields in this table","additionalProperties":{"$ref":"#/components/schemas/VirtualFieldMetaData"}}}},"TableQueryResponseV1":{"type":"object","properties":{"records":{"type":"array","description":"List of records that satisfy the query request","items":{"$ref":"#/components/schemas/OutputRecord"}}}},"TableSection":{"type":"object","properties":{"alternatives":{"type":"object","description":"Alternative versions of this section for specific screens, keyed by alternative type (for example RECORD_VIEW or RECORD_EDIT). A screen of that type uses the alternative in place of this definition. Omitted when there are none.","additionalProperties":{"$ref":"#/components/schemas/TableSection"}},"collapsible":{"description":"Whether screens that can collapse sections may collapse this one, and whether it starts open. Omitted when the section defines no collapsible behavior.","$ref":"#/components/schemas/TableSectionCollapsible"},"fieldNames":{"type":"array","description":"List of field names to include in this section."},"gridColumns":{"type":"number","description":"Layout suggestion, for how many columns of a 12-grid this section should use."},"helpContents":{"type":"array","description":"Help Contents for this section table.","items":{"$ref":"#/components/schemas/HelpContentV1"}},"icon":{"description":"Icon to display for the table","$ref":"#/components/schemas/Icon"},"label":{"type":"string","description":"User-facing label to display for this section"},"name":{"type":"string","description":"Unique identifier for this section within this table"},"tier":{"type":"string","description":"Importance of this section (T1, T2, or T3)"},"widgetName":{"type":"string","description":"Name of a widget in this QQQ instance to include in this section (instead of fields)."}}},"TableSectionCollapsible":{"type":"object","properties":{"initiallyOpen":{"type":"boolean","description":"Whether a collapsible section starts open, before the user has opened or closed it.","nullable":true},"isCollapsible":{"type":"boolean","description":"Whether screens that can collapse sections let the user collapse and expand this one.","nullable":true}}},"TableUpdateResponseV1":{"type":"object","properties":{"record":{"type":"object","description":"The record that was updated","properties":{"associatedRecords":{"type":"object","description":"Records associated with this record, keyed by association name. Each value is a list of records with the same shape as this one. Only present when associations were requested or written.","additionalProperties":{"type":"array"}},"displayValues":{"type":"object","description":"Formatted string versions of the values that make up the record. Keys are Strings, which match the table's field names. Values are all Strings."},"errors":{"type":"array","description":"Messages for errors on this record (for example on an associated record that could not be written). Omitted when there are none.","items":{"type":"string"}},"recordLabel":{"type":"string","description":"Label to identify the record to a user."},"tableName":{"type":"string","description":"Name of the table that the record is from."},"values":{"type":"object","description":"Raw values that make up the record. Keys are Strings, which match the table's field names. Values can be any type, as per the table's fields. Single-record responses (get, insert, update) include fields whose value is null; query results omit them."},"warnings":{"type":"array","description":"Messages for warnings on this record. Omitted when there are none.","items":{"type":"string"}}}},"warnings":{"type":"array","description":"Any warnings that occurred during the update","items":{"type":"string"}}}},"TableVariant":{"type":"object","properties":{"id":{"type":"string","description":"Identifier for the variant option (record) being used."},"name":{"type":"string","description":"A user-facing name (or label) for the variant option being used."},"type":{"type":"string","description":"Specification for the variant type (variantTypeKey from QQQ BackendVariantsConfig)"}}},"TableVariantsResponseV1":{"type":"object","properties":{"variants":{"type":"array","description":"The variants the table's backend can be scoped to - send one back as tableVariant in query, count, get and export requests. Empty (always present) when the backend does not use variants.","items":{"$ref":"#/components/schemas/TableVariant"}}}},"UiApiExtensionInfo":{"type":"object","properties":{"description":{"type":"string","description":"A short description of the extension."},"name":{"type":"string","description":"The extension namespace, e.g. alerts or sql-workbench."},"pathPrefix":{"type":"string","description":"The path prefix of the extension operations under the API base path, e.g. /qbit/backups or /esb."},"version":{"type":"string","description":"The extension semantic version (MAJOR.MINOR.PATCH)."}}},"UiSettings":{"type":"object","properties":{"processNamesToAddToAllQueryAndViewScreens":{"type":"array","description":"Visible processes offered on every query and record-view screen.","items":{"type":"string"}},"recordViewActionsPlacement":{"type":"string","description":"Placement of record-view actions."},"theme":{"type":"object","description":"Configured colors and font families; no web layout or CSS settings.","additionalProperties":{"type":"string"}},"weekdayCriteriaSettings":{"description":"Weekday query criteria configuration.","$ref":"#/components/schemas/MaterialDashboardWeekdayCriteriaSettings"}}},"UploadRefResponseV1":{"type":"object","properties":{"contentType":{"type":"string","description":"The file's content type, as uploaded."},"expiresAt":{"type":"string","description":"When the ref stops working (ISO-8601). A job that uses it extends it."},"fileName":{"type":"string","description":"The file's name."},"ref":{"type":"string","description":"Opaque ref to the uploaded file, bound to the uploading user. Pass it in uploadRefs."},"sizeBytes":{"type":"number","description":"The file's size in bytes."}}},"VersionResponseV1":{"type":"object","properties":{"apiVersion":{"type":"string","description":"Semantic version (MAJOR.MINOR.PATCH) of the UI API this server implements. MAJOR matches the URL version (v1). A client built against 1.x works with any server 1.y where y >= x."},"basePath":{"type":"string","description":"Base path of this API version, e.g. /qqq/v1."},"clientChannels":{"type":"array","description":"Client channel names the server accepts in the X-QQQ-Client request header (`channel[/detail]`, e.g. next-ui, assistant/). A client names itself on every request; it is recorded in audits and some objects are denied to some channels. The actor is always the signed-in user; a channel never grants anything.","items":{"type":"string"}},"extensions":{"type":"array","description":"Extensions (modules and qbits) registered on this server, each with its own path prefix and semantic version.","items":{"$ref":"#/components/schemas/UiApiExtensionInfo"}},"features":{"type":"array","description":"Names of the optional core features this server supports, so a client can show or hide an area without probing.","items":{"type":"string"}},"supportedMajorVersions":{"type":"array","description":"The major versions of the UI API this server serves.","items":{"type":"number"}}}},"VirtualFieldMetaData":{"type":"object","properties":{"accessTier":{"type":"string","description":"Effective field access: FULL, REVEALABLE, MASKED, or HIDDEN. Omitted means FULL. Restricted values are strings, regardless of field type.","enum":["FULL","REVEALABLE","MASKED","HIDDEN"]},"adornments":{"type":"array","description":"Special UI dressings to add to the field.","items":{"$ref":"#/components/schemas/FieldAdornment"}},"allowedFilterOperators":{"type":"array","description":"Allowed filter operators when restricted: EQUALS and IN for REVEALABLE when exact match is enabled, otherwise empty. Omitted means unrestricted.","items":{"type":"string"}},"behaviors":{"type":"array","description":"Names of the field's behaviors that a frontend applies while editing, e.g., TO_UPPER_CASE, TO_LOWER_CASE or TRIM. Absent when the field has none.","items":{"type":"string"}},"defaultValue":{"type":"string","description":"Default value to use in this field."},"displayFormat":{"type":"string","description":"C-style format specifier for displaying values in this field."},"gridColumns":{"type":"number","description":"Width of this field in a 12-column record form or view grid (e.g., 12 for the full width, 6 for half). Absent when the frontend's default applies."},"helpContents":{"type":"array","description":"Help Contents for this field.","items":{"$ref":"#/components/schemas/HelpContentV1"}},"inlinePossibleValueSource":{"type":"object","description":"Inline possible-value source for this field; enumValues supply choices without a separate lookup.","properties":{"customCodeReference":{"type":"object","properties":{"codeType":{"type":"string","enum":["JAVA","JAVA_SCRIPT"]},"inlineCode":{"type":"string"},"name":{"type":"string"}}},"enumValues":{"type":"array"},"helpContent":{"type":"object"},"idType":{"type":"string","enum":["STRING","INTEGER","LONG","DECIMAL","BOOLEAN","DATE","TIME","DATE_TIME","TEXT","HTML","PASSWORD","BLOB"]},"label":{"type":"string"},"name":{"type":"string"},"orderByFields":{"type":"array"},"overrideIdField":{"type":"string"},"picker":{"type":"object","properties":{"detailFields":{"type":"array"},"filterFields":{"type":"array"},"pageSize":{"type":"number"},"previewField":{"type":"string"},"searchFields":{"type":"array"},"sorts":{"type":"array"},"subtitleFields":{"type":"array"},"thumbnailField":{"type":"string"},"uploadProcessName":{"type":"string"},"uploadResultIdField":{"type":"string"}}},"searchFields":{"type":"array"},"tableName":{"type":"string"},"type":{"type":"string","enum":["ENUM","TABLE","CUSTOM"]},"valueFields":{"type":"array"},"valueFieldsIfNotFound":{"type":"array"},"valueFormat":{"type":"string"},"valueFormatIfNotFound":{"type":"string"}}},"isEditable":{"type":"boolean","description":"Indicate if user may edit the value in this field.","nullable":true},"isHeavy":{"type":"boolean","description":"Indicator of 'heavy' fields, which are not loaded by default. e.g., some blobs or long-texts","nullable":true},"isHidden":{"type":"boolean","description":"Indicate if this field should be hidden from users","nullable":true},"isQueryCriteria":{"type":"boolean","description":"Indicator of whether or not this virtual field can be included as a query filter criteria","nullable":true},"isQuerySelectable":{"type":"boolean","description":"Indicator of whether or not this virtual field can be included in query outputs (e.g., if it can be selected, in the SQL sense)","nullable":true},"isRequired":{"type":"boolean","description":"Indicate if a value in this field is required.","nullable":true},"isSortable":{"type":"boolean","description":"False for restricted fields; omitted means sortable.","nullable":true},"label":{"type":"string","description":"User-facing name for this field"},"maxLength":{"type":"number","description":"For String fields, the max length the field supports."},"maxValue":{"type":"string","description":"For number fields, the largest value the field accepts (inclusive). Absent when there is no such limit."},"minValue":{"type":"string","description":"For number fields, the smallest value the field accepts (inclusive). Absent when there is no such limit."},"name":{"type":"string","description":"Unique name for this field within its container (table or process)"},"picker":{"type":"object","description":"When this field's possible value source declares a record picker (for sources over large tables), its configuration: thumbnail, preview, subtitle and detail fields, filter fields, search fields, sorts and page size. Frontends offer a searchable, paged picker dialog.","properties":{"detailFields":{"type":"array"},"filterFields":{"type":"array"},"pageSize":{"type":"number"},"previewField":{"type":"string"},"searchFields":{"type":"array"},"sorts":{"type":"array"},"subtitleFields":{"type":"array"},"thumbnailField":{"type":"string"},"uploadProcessName":{"type":"string"},"uploadResultIdField":{"type":"string"}}},"pickerTableName":{"type":"string","description":"When this field has a picker, the table its possible value source reads, whose metadata describes the picker's fields."},"possibleValueSourceDependencyBehavior":{"type":"string","description":"DISABLE_UNTIL_SET disables a contingent field until its dependencies are set (default). SHOW_ALL_UNTIL_SET keeps it enabled and omits criteria with missing inputs in form searches. Absent for non-contingent fields.","enum":["DISABLE_UNTIL_SET","SHOW_ALL_UNTIL_SET"]},"possibleValueSourceDependsOn":{"type":"array","description":"Names of fields controlling this field's choices, including explicit and filter dependencies. Absent for non-contingent fields.","items":{"type":"string"}},"possibleValueSourceName":{"type":"string","description":"If this field's values should come from a possible value source, then that PVS is named here."},"supplementalMetaData":{"type":"object","description":"Additional frontend-visible metadata for this field, keyed by supplemental type."},"type":{"type":"string","description":"Data-type for this field"},"validation":{"description":"The field's validation rules, as the server enforces them on insert and update (required, maxLength and tooLongBehavior, min/max value, pattern). Absent when the field has none. Since 1.6.0.","$ref":"#/components/schemas/FieldValidationV1"}}},"WeekdayCriteriaArguments":{"type":"object","properties":{"timeZoneId":{"type":"string"},"useSessionZoneId":{"type":"boolean"}},"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}]}},"WidgetBlock":{"type":"object","properties":{"blockId":{"type":"string","description":"Unique identifier for this block within it widget. Used as a key for helpContents."},"blockType":{"type":"string","description":"What type of block to render.","enum":["BUTTON","AUDIO","BIG_NUMBER","COMPOSITE","DIVIDER","IMAGE","INPUT_FIELD","NUMBER_ICON_BADGE","PROGRESS_BAR","TABLE_SUB_ROW_DETAIL_ROW","TEXT","UP_OR_DOWN_NUMBER"]},"blockTypeName":{"type":"string","description":"Name of the block's type, as the backend declares it (including types this API version does not enumerate in blockType)."},"conditional":{"type":"string","description":"Optional field name (e.g,. from a process's set of fields) to act as a 'guard' for the block - e.g., only include it in the UI if the value for this field is true"},"footerText":{"type":"string","description":"Footer as plain text."},"layout":{"type":"string","description":"For COMPOSITE type blocks, an indicator of how the sub-blocks should be laid out","enum":["FLEX_COLUMN","FLEX_ROW_WRAPPED","FLEX_ROW_SPACE_BETWEEN","FLEX_ROW_CENTER","TABLE_SUB_ROW_DETAILS","BADGES_WRAPPER"]},"modalMode":{"type":"string","description":"For COMPOSITE type blocks, optional control to make the widget appear modally","enum":["MODAL"]},"overlayHtml":{"type":"string","description":"Composite overlay as HTML."},"overlayText":{"type":"string","description":"Composite overlay as plain text."},"styles":{"description":"Styles to apply to the block. Different fields based on blockType.","oneOf":[{"type":"object","properties":{"backgroundColor":{"type":"string","description":"A background color to use for the block"},"padding":{"type":"object","description":"Optional padding to apply to the block","properties":{"bottom":{"type":"object"},"left":{"type":"object"},"right":{"type":"object"},"top":{"type":"object"}}}}},{"type":"object","properties":{"color":{"type":"string","description":"A Color to use for the button. May be specified as a StandardColor (one of: SUCCESS, WARNING, ERROR, INFO, MUTED) or an RGB code."},"format":{"type":"string","description":"An optional indicator of the screen format preferred by the application to be used for this block, such as OUTLINED, FILLED, or TEXT. Different frontends may support different formats, and implement them differently."}}},{"type":"object","properties":{"height":{"type":"string","description":"A request to render the image at a specified height."},"padding":{"type":"object","description":"Optional padding to apply to the image","properties":{"bottom":{"type":"object"},"left":{"type":"object"},"right":{"type":"object"},"top":{"type":"object"}}},"width":{"type":"string","description":"A request to render the image at a specified width."}}},{"type":"object","properties":{"color":{"type":"string","description":"A Color to display the text in. May be specified as a StandardColor (one of: SUCCESS, WARNING, ERROR, INFO, MUTED) or an RGB code."},"format":{"type":"string","description":"An optional indicator of the screen format preferred by the application to be used for this block. Different frontends may support different formats, and implement them differently."},"size":{"type":"string","description":"An optional indicator of the size at which the text should be rendered. May be a named value (one oflargest, headline, title, body, smallest) or a numeric size - both are up to the frontend to interpret."},"weight":{"type":"string","description":"An optional indicator of the weight at which the text should be rendered. May be a named value (one ofextralight, thin, medium, black, semibold, bold, extrabold) or a numeric, e.g., 100, 200, ..., 900"}}}],"$ref":"#/components/schemas/WidgetBlockStyles"},"subBlocks":{"type":"array","description":"For COMPOSITE type blocks, a list of sub-blocks.","items":{"$ref":"#/components/schemas/WidgetBlock"}},"values":{"description":"Values to show in the block, or otherwise control its behavior. Different fields based on blockType.","oneOf":[{"type":"object","description":"Values used for an AUDIO type widget block","properties":{"autoPlay":{"type":"boolean","description":"Control if the file should automatically play when the block is rendered","nullable":true},"path":{"type":"string","description":"The path to the audio file on the server"},"showControls":{"type":"boolean","description":"Control if on-screen controls should be shown to allow the user to control playback","nullable":true}}},{"type":"object","description":"Values used for a BUTTON type widget block","properties":{"actionCode":{"type":"string","description":"Code used within the app as the value submitted when the button is clicked"},"controlCode":{"type":"string","description":"Instructions for what should happen in the frontend (e.g., within a screen), when the button is clicked.\n\nTo show a modal composite block, use format: `showModal:${blockId}` (e.g., `showModal:myBlock`)\n\nTo hide a modal composite block, use format: `hideModal:${blockId}` (e.g., `hideModal:myBlock`)\n\nTo toggle visibility of a modal composite block, use format: `toggleModal:${blockId}` (e.g., `toggleModal:myBlock`)\n"},"endIcon":{"type":"object","description":"An optional icon to display after the text in the button","properties":{"color":{"type":"string","description":"A color code to use for displaying the icon"},"name":{"type":"string","description":"Material UI icon name (web); prefer semanticName"},"path":{"type":"string","description":"A path to an image file that can be requested from the server, to serve as the icon image instead of a material UI icon."},"semanticName":{"type":"string","description":"Client-neutral kebab-case icon token; null when unmapped."}}},"label":{"type":"string","description":"User-facing label to display in the button"},"startIcon":{"type":"object","description":"An optional icon to display before the text in the button","properties":{"color":{"type":"string","description":"A color code to use for displaying the icon"},"name":{"type":"string","description":"Material UI icon name (web); prefer semanticName"},"path":{"type":"string","description":"A path to an image file that can be requested from the server, to serve as the icon image instead of a material UI icon."},"semanticName":{"type":"string","description":"Client-neutral kebab-case icon token; null when unmapped."}}}}},{"type":"object","description":"Values used for an IMAGE type widget block","properties":{"path":{"type":"string","description":"The path to the image on the server"}}},{"type":"object","description":"Values used for an INPUT_FIELD type widget block","properties":{"autoFocus":{"type":"boolean","description":"Indicate whether this field should auto-focus when it is rendered","nullable":true},"fieldMetaData":{"type":"object","description":"Metadata to define the field that this block controls","properties":{"accessTier":{"type":"string","description":"Effective field access: FULL, REVEALABLE, MASKED, or HIDDEN. Omitted means FULL. Restricted values are strings, regardless of field type.","enum":["FULL","REVEALABLE","MASKED","HIDDEN"]},"adornments":{"type":"array","description":"Special UI dressings to add to the field.","items":{"$ref":"#/components/schemas/FieldAdornment"}},"allowedFilterOperators":{"type":"array","description":"Allowed filter operators when restricted: EQUALS and IN for REVEALABLE when exact match is enabled, otherwise empty. Omitted means unrestricted.","items":{"type":"string"}},"behaviors":{"type":"array","description":"Names of the field's behaviors that a frontend applies while editing, e.g., TO_UPPER_CASE, TO_LOWER_CASE or TRIM. Absent when the field has none.","items":{"type":"string"}},"defaultValue":{"type":"string","description":"Default value to use in this field."},"displayFormat":{"type":"string","description":"C-style format specifier for displaying values in this field."},"gridColumns":{"type":"number","description":"Width of this field in a 12-column record form or view grid (e.g., 12 for the full width, 6 for half). Absent when the frontend's default applies."},"helpContents":{"type":"array","description":"Help Contents for this field.","items":{"$ref":"#/components/schemas/HelpContentV1"}},"inlinePossibleValueSource":{"type":"object","description":"Inline possible-value source for this field; enumValues supply choices without a separate lookup.","properties":{"customCodeReference":{"type":"object","properties":{"codeType":{"type":"string","enum":["JAVA","JAVA_SCRIPT"]},"inlineCode":{"type":"string"},"name":{"type":"string"}}},"enumValues":{"type":"array"},"helpContent":{"type":"object"},"idType":{"type":"string","enum":["STRING","INTEGER","LONG","DECIMAL","BOOLEAN","DATE","TIME","DATE_TIME","TEXT","HTML","PASSWORD","BLOB"]},"label":{"type":"string"},"name":{"type":"string"},"orderByFields":{"type":"array"},"overrideIdField":{"type":"string"},"picker":{"type":"object","properties":{"detailFields":{"type":"array"},"filterFields":{"type":"array"},"pageSize":{"type":"number"},"previewField":{"type":"string"},"searchFields":{"type":"array"},"sorts":{"type":"array"},"subtitleFields":{"type":"array"},"thumbnailField":{"type":"string"},"uploadProcessName":{"type":"string"},"uploadResultIdField":{"type":"string"}}},"searchFields":{"type":"array"},"tableName":{"type":"string"},"type":{"type":"string","enum":["ENUM","TABLE","CUSTOM"]},"valueFields":{"type":"array"},"valueFieldsIfNotFound":{"type":"array"},"valueFormat":{"type":"string"},"valueFormatIfNotFound":{"type":"string"}}},"isEditable":{"type":"boolean","description":"Indicate if user may edit the value in this field.","nullable":true},"isHeavy":{"type":"boolean","description":"Indicator of 'heavy' fields, which are not loaded by default. e.g., some blobs or long-texts","nullable":true},"isHidden":{"type":"boolean","description":"Indicate if this field should be hidden from users","nullable":true},"isRequired":{"type":"boolean","description":"Indicate if a value in this field is required.","nullable":true},"isSortable":{"type":"boolean","description":"False for restricted fields; omitted means sortable.","nullable":true},"label":{"type":"string","description":"User-facing name for this field"},"maxLength":{"type":"number","description":"For String fields, the max length the field supports."},"maxValue":{"type":"string","description":"For number fields, the largest value the field accepts (inclusive). Absent when there is no such limit."},"minValue":{"type":"string","description":"For number fields, the smallest value the field accepts (inclusive). Absent when there is no such limit."},"name":{"type":"string","description":"Unique name for this field within its container (table or process)"},"picker":{"type":"object","description":"When this field's possible value source declares a record picker (for sources over large tables), its configuration: thumbnail, preview, subtitle and detail fields, filter fields, search fields, sorts and page size. Frontends offer a searchable, paged picker dialog.","properties":{"detailFields":{"type":"array"},"filterFields":{"type":"array"},"pageSize":{"type":"number"},"previewField":{"type":"string"},"searchFields":{"type":"array"},"sorts":{"type":"array"},"subtitleFields":{"type":"array"},"thumbnailField":{"type":"string"},"uploadProcessName":{"type":"string"},"uploadResultIdField":{"type":"string"}}},"pickerTableName":{"type":"string","description":"When this field has a picker, the table its possible value source reads, whose metadata describes the picker's fields."},"possibleValueSourceDependencyBehavior":{"type":"string","description":"DISABLE_UNTIL_SET disables a contingent field until its dependencies are set (default). SHOW_ALL_UNTIL_SET keeps it enabled and omits criteria with missing inputs in form searches. Absent for non-contingent fields.","enum":["DISABLE_UNTIL_SET","SHOW_ALL_UNTIL_SET"]},"possibleValueSourceDependsOn":{"type":"array","description":"Names of fields controlling this field's choices, including explicit and filter dependencies. Absent for non-contingent fields.","items":{"type":"string"}},"possibleValueSourceName":{"type":"string","description":"If this field's values should come from a possible value source, then that PVS is named here."},"supplementalMetaData":{"type":"object","description":"Additional frontend-visible metadata for this field, keyed by supplemental type."},"type":{"type":"string","description":"Data-type for this field"},"validation":{"type":"object","description":"The field's validation rules, as the server enforces them on insert and update (required, maxLength and tooLongBehavior, min/max value, pattern). Absent when the field has none. Since 1.6.0.","properties":{"maxInclusive":{"type":"boolean","description":"Whether maxValue itself is accepted (false: the value must be less).","nullable":true},"maxLength":{"type":"number","description":"For string fields, the most characters the field stores. What happens to a longer value is tooLongBehavior."},"maxValue":{"type":"string","description":"For number fields, the largest value accepted (plain digits, exact). See maxInclusive."},"minInclusive":{"type":"boolean","description":"Whether minValue itself is accepted (false: the value must be greater).","nullable":true},"minValue":{"type":"string","description":"For number fields, the smallest value accepted (plain digits, exact). See minInclusive."},"pattern":{"type":"string","description":"A regular expression a non-empty value must match as a whole (written to mean the same in Java and ECMAScript)."},"patternMessage":{"type":"string","description":"The message the server gives for a value that does not match pattern."},"required":{"type":"boolean","description":"True when a value is required.","nullable":true},"tooLongBehavior":{"type":"string","description":"With maxLength: ERROR (a longer value is refused), TRUNCATE or TRUNCATE_ELLIPSIS (it is trimmed on save), PASS_THROUGH (neither)."}}}}},"hideSoftKeyboard":{"type":"boolean","description":"Indicate if the frontend uses a software/on-screen keyboard, if the application should try to hide it (e.g., upon auto-focus).","nullable":true},"placeholder":{"type":"string","description":"Optional placeholder text to display in the input box."},"submitOnEnter":{"type":"boolean","description":"Indicate whether the form that this field is on should be submitted when Enter is pressed","nullable":true}}},{"type":"object","description":"Values used for a TEXT type widget block","properties":{"endIcon":{"type":"object","description":"An optional icon to display after the text","properties":{"color":{"type":"string","description":"A color code to use for displaying the icon"},"name":{"type":"string","description":"Material UI icon name (web); prefer semanticName"},"path":{"type":"string","description":"A path to an image file that can be requested from the server, to serve as the icon image instead of a material UI icon."},"semanticName":{"type":"string","description":"Client-neutral kebab-case icon token; null when unmapped."}}},"startIcon":{"type":"object","description":"An optional icon to display before the text","properties":{"color":{"type":"string","description":"A color code to use for displaying the icon"},"name":{"type":"string","description":"Material UI icon name (web); prefer semanticName"},"path":{"type":"string","description":"A path to an image file that can be requested from the server, to serve as the icon image instead of a material UI icon."},"semanticName":{"type":"string","description":"Client-neutral kebab-case icon token; null when unmapped."}}},"text":{"type":"string","description":"The text to display in the block"}}}],"$ref":"#/components/schemas/WidgetBlockValues"}}},"WidgetBlockAudioValues":{"type":"object","description":"Values used for an AUDIO type widget block","properties":{"autoPlay":{"type":"boolean","description":"Control if the file should automatically play when the block is rendered","nullable":true},"path":{"type":"string","description":"The path to the audio file on the server"},"showControls":{"type":"boolean","description":"Control if on-screen controls should be shown to allow the user to control playback","nullable":true}}},"WidgetBlockBaseStyles":{"type":"object","properties":{"backgroundColor":{"type":"string","description":"A background color to use for the block"},"padding":{"type":"object","description":"Optional padding to apply to the block","properties":{"bottom":{"type":"object"},"left":{"type":"object"},"right":{"type":"object"},"top":{"type":"object"}}}}},"WidgetBlockButtonStyles":{"type":"object","properties":{"color":{"type":"string","description":"A Color to use for the button. May be specified as a StandardColor (one of: SUCCESS, WARNING, ERROR, INFO, MUTED) or an RGB code."},"format":{"type":"string","description":"An optional indicator of the screen format preferred by the application to be used for this block, such as OUTLINED, FILLED, or TEXT. Different frontends may support different formats, and implement them differently."}}},"WidgetBlockButtonValues":{"type":"object","description":"Values used for a BUTTON type widget block","properties":{"actionCode":{"type":"string","description":"Code used within the app as the value submitted when the button is clicked"},"controlCode":{"type":"string","description":"Instructions for what should happen in the frontend (e.g., within a screen), when the button is clicked.\n\nTo show a modal composite block, use format: `showModal:${blockId}` (e.g., `showModal:myBlock`)\n\nTo hide a modal composite block, use format: `hideModal:${blockId}` (e.g., `hideModal:myBlock`)\n\nTo toggle visibility of a modal composite block, use format: `toggleModal:${blockId}` (e.g., `toggleModal:myBlock`)\n"},"endIcon":{"description":"An optional icon to display after the text in the button","$ref":"#/components/schemas/Icon"},"label":{"type":"string","description":"User-facing label to display in the button"},"startIcon":{"description":"An optional icon to display before the text in the button","$ref":"#/components/schemas/Icon"}}},"WidgetBlockImageStyles":{"type":"object","properties":{"height":{"type":"string","description":"A request to render the image at a specified height."},"padding":{"type":"object","description":"Optional padding to apply to the image","properties":{"bottom":{"type":"object"},"left":{"type":"object"},"right":{"type":"object"},"top":{"type":"object"}}},"width":{"type":"string","description":"A request to render the image at a specified width."}}},"WidgetBlockImageValues":{"type":"object","description":"Values used for an IMAGE type widget block","properties":{"path":{"type":"string","description":"The path to the image on the server"}}},"WidgetBlockInputFieldValues":{"type":"object","description":"Values used for an INPUT_FIELD type widget block","properties":{"autoFocus":{"type":"boolean","description":"Indicate whether this field should auto-focus when it is rendered","nullable":true},"fieldMetaData":{"description":"Metadata to define the field that this block controls","$ref":"#/components/schemas/FieldMetaData"},"hideSoftKeyboard":{"type":"boolean","description":"Indicate if the frontend uses a software/on-screen keyboard, if the application should try to hide it (e.g., upon auto-focus).","nullable":true},"placeholder":{"type":"string","description":"Optional placeholder text to display in the input box."},"submitOnEnter":{"type":"boolean","description":"Indicate whether the form that this field is on should be submitted when Enter is pressed","nullable":true}}},"WidgetBlockStyles":{"type":"object"},"WidgetBlockTextStyles":{"type":"object","properties":{"color":{"type":"string","description":"A Color to display the text in. May be specified as a StandardColor (one of: SUCCESS, WARNING, ERROR, INFO, MUTED) or an RGB code."},"format":{"type":"string","description":"An optional indicator of the screen format preferred by the application to be used for this block. Different frontends may support different formats, and implement them differently."},"size":{"type":"string","description":"An optional indicator of the size at which the text should be rendered. May be a named value (one oflargest, headline, title, body, smallest) or a numeric size - both are up to the frontend to interpret."},"weight":{"type":"string","description":"An optional indicator of the weight at which the text should be rendered. May be a named value (one ofextralight, thin, medium, black, semibold, bold, extrabold) or a numeric, e.g., 100, 200, ..., 900"}}},"WidgetBlockTextValues":{"type":"object","description":"Values used for a TEXT type widget block","properties":{"endIcon":{"description":"An optional icon to display after the text","$ref":"#/components/schemas/Icon"},"startIcon":{"description":"An optional icon to display before the text","$ref":"#/components/schemas/Icon"},"text":{"type":"string","description":"The text to display in the block"}}},"WidgetBlockValues":{"type":"object"},"WidgetData":{"description":"The data of a widget: one of the per-type shapes, chosen by `type` (the widget type). Clients render by type and ignore unknown properties; an unknown type is rendered as the widget label with its footerHTML/label only.","oneOf":[{"$ref":"#/components/schemas/WidgetDataAlert"},{"$ref":"#/components/schemas/WidgetDataChart"},{"$ref":"#/components/schemas/WidgetDataLineChart"},{"$ref":"#/components/schemas/WidgetDataPieChart"},{"$ref":"#/components/schemas/WidgetDataChildRecordList"},{"$ref":"#/components/schemas/WidgetDataComposite"},{"$ref":"#/components/schemas/WidgetDataCronUI"},{"$ref":"#/components/schemas/WidgetDataDivider"},{"$ref":"#/components/schemas/WidgetDataDynamicForm"},{"$ref":"#/components/schemas/WidgetDataFieldValueList"},{"$ref":"#/components/schemas/WidgetDataFilterAndColumnsSetup"},{"$ref":"#/components/schemas/WidgetDataLocation"},{"$ref":"#/components/schemas/WidgetDataMultiStatistics"},{"$ref":"#/components/schemas/WidgetDataMultiTable"},{"$ref":"#/components/schemas/WidgetDataParent"},{"$ref":"#/components/schemas/WidgetDataProcess"},{"$ref":"#/components/schemas/WidgetDataQuickSightChart"},{"$ref":"#/components/schemas/WidgetDataRawHTML"},{"$ref":"#/components/schemas/WidgetDataRowBuilder"},{"$ref":"#/components/schemas/WidgetDataStatistics"},{"$ref":"#/components/schemas/WidgetDataStepper"},{"$ref":"#/components/schemas/WidgetDataTable"},{"$ref":"#/components/schemas/WidgetDataUSMap"},{"$ref":"#/components/schemas/WidgetDataGeneric"}],"discriminator":{"propertyName":"type","mapping":{"alert":"#/components/schemas/WidgetDataAlert","barChart":"#/components/schemas/WidgetDataChart","chart":"#/components/schemas/WidgetDataChart","childRecordList":"#/components/schemas/WidgetDataChildRecordList","composite":"#/components/schemas/WidgetDataComposite","cronUI":"#/components/schemas/WidgetDataCronUI","customComponent":"#/components/schemas/WidgetDataGeneric","dataBagViewer":"#/components/schemas/WidgetDataGeneric","divider":"#/components/schemas/WidgetDataDivider","dynamicForm":"#/components/schemas/WidgetDataDynamicForm","fieldValueList":"#/components/schemas/WidgetDataFieldValueList","filterAndColumnsSetup":"#/components/schemas/WidgetDataFilterAndColumnsSetup","generic":"#/components/schemas/WidgetDataGeneric","horizontalBarChart":"#/components/schemas/WidgetDataChart","html":"#/components/schemas/WidgetDataRawHTML","lineChart":"#/components/schemas/WidgetDataLineChart","location":"#/components/schemas/WidgetDataLocation","multiStatistics":"#/components/schemas/WidgetDataMultiStatistics","multiTable":"#/components/schemas/WidgetDataMultiTable","parentWidget":"#/components/schemas/WidgetDataParent","pieChart":"#/components/schemas/WidgetDataPieChart","pivotTableSetup":"#/components/schemas/WidgetDataGeneric","process":"#/components/schemas/WidgetDataProcess","quickSightChart":"#/components/schemas/WidgetDataQuickSightChart","rowBuilder":"#/components/schemas/WidgetDataRowBuilder","scriptViewer":"#/components/schemas/WidgetDataGeneric","smallLineChart":"#/components/schemas/WidgetDataLineChart","stackedBarChart":"#/components/schemas/WidgetDataChart","statistics":"#/components/schemas/WidgetDataStatistics","stepper":"#/components/schemas/WidgetDataStepper","table":"#/components/schemas/WidgetDataTable","usaMap":"#/components/schemas/WidgetDataUSMap"}}},"WidgetDataAlert":{"type":"object","description":"Data of alert widgets.","properties":{"alertType":{"type":"string","nullable":true,"enum":["ERROR","SUCCESS","WARNING"]},"bulletList":{"type":"array"},"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"hideWidget":{"type":"boolean","nullable":true},"html":{"type":"string","nullable":true},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"sublabel":{"type":"string","description":"Secondary title."},"text":{"type":"string","description":"Plain text equivalent of html, preserving link text and line breaks."},"type":{"type":"string","description":"The widget type this data is for.","enum":["alert"]}}},"WidgetDataChart":{"type":"object","description":"Data of chart, barChart, horizontalBarChart, and stackedBarChart widgets.","properties":{"chartData":{"type":"object","properties":{"datasets":{"type":"array","items":{"type":"object","properties":{"backgroundColor":{"type":"string"},"backgroundColors":{"type":"array","description":"Colors per data point.","items":{"type":"string"}},"color":{"type":"string"},"data":{"type":"array","items":{"type":"number","nullable":true}},"label":{"type":"string"},"urls":{"type":"array","description":"Links per data point.","items":{"type":"string"}}}}},"labels":{"type":"array","description":"Labels per data point.","items":{"type":"string"}},"lineLabels":{"type":"array","description":"Labels of the lines.","items":{"type":"string"}},"urls":{"type":"array","description":"Links per data point.","items":{"type":"string"}}}},"chartSubheaderData":{"type":"object","properties":{"isGoodVsPrevious":{"type":"boolean","nullable":true},"isUpVsPrevious":{"type":"boolean","nullable":true},"mainNumber":{"type":"number"},"mainNumberUrl":{"type":"string"},"previousNumberUrl":{"type":"string"},"vsDescription":{"type":"string"},"vsPreviousNumber":{"type":"number"},"vsPreviousPercent":{"type":"number"}}},"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"description":{"type":"string","nullable":true},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"height":{"type":"integer"},"isCurrency":{"type":"boolean"},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"sublabel":{"type":"string","description":"Secondary title."},"title":{"type":"string","nullable":true},"type":{"type":"string","description":"The widget type this data is for.","enum":["chart","barChart","horizontalBarChart","stackedBarChart"]}}},"WidgetDataChildRecordList":{"type":"object","description":"Data of childRecordList widgets.","properties":{"allowRecordDelete":{"type":"boolean","nullable":true},"allowRecordEdit":{"type":"boolean","nullable":true},"canAddChildRecord":{"type":"boolean"},"childFrontendTableMetaData":{"type":"object","$ref":"#/components/schemas/TableMetaData"},"childTableMetaData":{"type":"object","$ref":"#/components/schemas/TableMetaData"},"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"defaultValuesForNewChildRecords":{"type":"object"},"defaultValuesForNewChildRecordsFromParentFields":{"type":"object"},"disableRowClick":{"type":"boolean","nullable":true},"disabledFieldsForNewChildRecords":{"type":"array","description":"Fields disabled when adding a child record.","items":{"type":"string"}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"includeExposedJoinTables":{"type":"array"},"isInProcess":{"type":"boolean","nullable":true},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"omitFieldNames":{"type":"array"},"onlyIncludeFieldNames":{"type":"array"},"queryOutput":{"type":"object","properties":{"records":{"type":"array","items":{"$ref":"#/components/schemas/OutputRecord"}}}},"sublabel":{"type":"string","description":"Secondary title."},"tableName":{"type":"string","nullable":true},"tablePath":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"totalRows":{"type":"number","nullable":true},"type":{"type":"string","description":"The widget type this data is for.","enum":["childRecordList"]},"viewAllLink":{"type":"string","nullable":true}}},"WidgetDataComposite":{"type":"object","description":"Data of composite widgets.","properties":{"blockId":{"type":"string","nullable":true},"blocks":{"type":"array"},"conditional":{"type":"string","nullable":true},"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"layout":{"type":"string","nullable":true,"enum":["FLEX_COLUMN","FLEX_ROW","FLEX_ROW_WRAPPED","FLEX_ROW_SPACE_BETWEEN","FLEX_ROW_CENTER","TABLE_SUB_ROW_DETAILS","BADGES_WRAPPER"]},"link":{"type":"object","properties":{"href":{"type":"string"}}},"linkMap":{"type":"object"},"modalMode":{"type":"string","nullable":true,"enum":["MODAL"]},"overlayHtml":{"type":"string","nullable":true},"overlayStyleOverrides":{"type":"object"},"overlayText":{"type":"string","description":"Plain text equivalent of overlayHtml, preserving link text and line breaks."},"styleOverrides":{"type":"object"},"styles":{"type":"object","properties":{"backgroundColor":{"type":"string","nullable":true},"padding":{"type":"object","properties":{"bottom":{"type":"string","nullable":true},"left":{"type":"string","nullable":true},"right":{"type":"string","nullable":true},"top":{"type":"string","nullable":true}}}}},"sublabel":{"type":"string","description":"Secondary title."},"tooltip":{"type":"object","properties":{"blockData":{"type":"object","properties":{"blocks":{"type":"array"},"layout":{"type":"string","enum":["FLEX_COLUMN","FLEX_ROW","FLEX_ROW_WRAPPED","FLEX_ROW_SPACE_BETWEEN","FLEX_ROW_CENTER","TABLE_SUB_ROW_DETAILS","BADGES_WRAPPER"]},"modalMode":{"type":"string","enum":["MODAL"]},"overlayHtml":{"type":"string"},"overlayStyleOverrides":{"type":"object"},"styleOverrides":{"type":"object"}}},"placement":{"type":"string","enum":["BOTTOM","LEFT","RIGHT","TOP"]},"title":{"type":"string"}}},"tooltipMap":{"type":"object"},"type":{"type":"string","description":"The widget type this data is for.","enum":["composite"]},"values":{"type":"object","description":"Composite BaseValues has no predefined members."}}},"WidgetDataCronUI":{"type":"object","description":"Data of cronUI widgets.","properties":{"cronDescription":{"type":"string","nullable":true},"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"error":{"type":"string","nullable":true},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"sublabel":{"type":"string","description":"Secondary title."},"type":{"type":"string","description":"The widget type this data is for.","enum":["cronUI"]}}},"WidgetDataDivider":{"type":"object","description":"Data of divider widgets.","properties":{"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"sublabel":{"type":"string","description":"Secondary title."},"type":{"type":"string","description":"The widget type this data is for.","enum":["divider"]}}},"WidgetDataDynamicForm":{"type":"object","description":"Data of dynamicForm widgets.","properties":{"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"fieldList":{"type":"array"},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"mergedDynamicFormValuesIntoFieldName":{"type":"string","nullable":true},"noFieldsMessage":{"type":"string","nullable":true},"recordOfFieldValues":{"type":"object","$ref":"#/components/schemas/OutputRecord"},"sublabel":{"type":"string","description":"Secondary title."},"type":{"type":"string","description":"The widget type this data is for.","enum":["dynamicForm"]}}},"WidgetDataFieldValueList":{"type":"object","description":"Data of fieldValueList widgets.","properties":{"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"fieldIndentLevels":{"type":"object"},"fieldLabelPrefixIconColors":{"type":"object"},"fieldLabelPrefixIconNames":{"type":"object"},"fields":{"type":"array"},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"record":{"type":"object","$ref":"#/components/schemas/OutputRecord"},"sublabel":{"type":"string","description":"Secondary title."},"type":{"type":"string","description":"The widget type this data is for.","enum":["fieldValueList"]}}},"WidgetDataFilterAndColumnsSetup":{"type":"object","description":"Data of filterAndColumnsSetup widgets.","properties":{"allowVariables":{"type":"boolean","nullable":true},"apiName":{"type":"string","nullable":true},"apiPath":{"type":"string","nullable":true},"apiVersion":{"type":"string","nullable":true},"columnFieldName":{"type":"string","nullable":true},"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"editButtonLabel":{"type":"string","nullable":true},"filterDefaultFieldNameSourceFieldNames":{"type":"object"},"filterDefaultFieldNames":{"type":"array"},"filterFieldName":{"type":"string","nullable":true},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"hideColumns":{"type":"boolean","nullable":true},"hidePreview":{"type":"boolean","nullable":true},"hideSortBy":{"type":"boolean","nullable":true},"isApiVersioned":{"type":"boolean","nullable":true},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"modalHeader":{"type":"string","nullable":true},"omitExposedJoins":{"type":"array"},"overrideIsEditable":{"type":"boolean","nullable":true},"sublabel":{"type":"string","description":"Secondary title."},"tableName":{"type":"string","nullable":true},"type":{"type":"string","description":"The widget type this data is for.","enum":["filterAndColumnsSetup"]}}},"WidgetDataGeneric":{"type":"object","description":"Data of widget types without a fixed shape (generic, customComponent, dataBagViewer, pivotTableSetup, and scriptViewer): the common properties plus widget-specific ones.","properties":{"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"footerText":{"type":"string","description":"Plain-text footer, preserving link text and line breaks."},"sublabel":{"type":"string","description":"Secondary title."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"type":{"type":"string","description":"The widget type this data is for.","enum":["generic","customComponent","dataBagViewer","pivotTableSetup","scriptViewer"]}},"additionalProperties":true},"WidgetDataLineChart":{"type":"object","description":"Data of lineChart and smallLineChart widgets.","properties":{"chartData":{"type":"object","properties":{"datasets":{"type":"array","items":{"type":"object","properties":{"backgroundColor":{"type":"string"},"backgroundColors":{"type":"array","description":"Colors per data point.","items":{"type":"string"}},"color":{"type":"string"},"data":{"type":"array","items":{"type":"number","nullable":true}},"label":{"type":"string"},"urls":{"type":"array","description":"Links per data point.","items":{"type":"string"}}}}},"labels":{"type":"array","description":"Labels per data point.","items":{"type":"string"}},"lineLabels":{"type":"array","description":"Labels of the lines.","items":{"type":"string"}},"urls":{"type":"array","description":"Links per data point.","items":{"type":"string"}}}},"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"isYAxisCurrency":{"type":"boolean"},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"sublabel":{"type":"string","description":"Secondary title."},"title":{"type":"string","nullable":true},"type":{"type":"string","description":"The widget type this data is for.","enum":["lineChart","smallLineChart"]}}},"WidgetDataLocation":{"type":"object","description":"Data of location widgets.","properties":{"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"description":{"type":"string","nullable":true},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"imageUrl":{"type":"string","nullable":true},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"location":{"type":"string","nullable":true},"sublabel":{"type":"string","description":"Secondary title."},"title":{"type":"string","nullable":true},"type":{"type":"string","description":"The widget type this data is for.","enum":["location"]}}},"WidgetDataMultiStatistics":{"type":"object","description":"Data of multiStatistics widgets.","properties":{"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"statisticsGroupData":{"type":"array"},"sublabel":{"type":"string","description":"Secondary title."},"title":{"type":"string","nullable":true},"type":{"type":"string","description":"The widget type this data is for.","enum":["multiStatistics"]}}},"WidgetDataMultiTable":{"type":"object","description":"Data of multiTable widgets.","properties":{"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"sublabel":{"type":"string","description":"Secondary title."},"tableDataList":{"type":"array"},"type":{"type":"string","description":"The widget type this data is for.","enum":["multiTable"]}}},"WidgetDataParent":{"type":"object","description":"Data of parentWidget widgets.","properties":{"childWidgetNameList":{"type":"array"},"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"isLabelPageTitle":{"type":"boolean"},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"layoutType":{"type":"string","nullable":true,"enum":["GRID","TABS"]},"sublabel":{"type":"string","description":"Secondary title."},"type":{"type":"string","description":"The widget type this data is for.","enum":["parentWidget"]}}},"WidgetDataPieChart":{"type":"object","description":"Data of pieChart widgets.","properties":{"chartData":{"type":"object","properties":{"datasets":{"type":"array","items":{"type":"object","properties":{"backgroundColor":{"type":"string"},"backgroundColors":{"type":"array","description":"Colors per data point.","items":{"type":"string"}},"color":{"type":"string"},"data":{"type":"array","items":{"type":"number","nullable":true}},"label":{"type":"string"},"urls":{"type":"array","description":"Links per data point.","items":{"type":"string"}}}}},"labels":{"type":"array","description":"Labels per data point.","items":{"type":"string"}},"lineLabels":{"type":"array","description":"Labels of the lines.","items":{"type":"string"}},"urls":{"type":"array","description":"Links per data point.","items":{"type":"string"}}}},"chartSubheaderData":{"type":"object","properties":{"isGoodVsPrevious":{"type":"boolean","nullable":true},"isUpVsPrevious":{"type":"boolean","nullable":true},"mainNumber":{"type":"number"},"mainNumberUrl":{"type":"string"},"previousNumberUrl":{"type":"string"},"vsDescription":{"type":"string"},"vsPreviousNumber":{"type":"number"},"vsPreviousPercent":{"type":"number"}}},"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"description":{"type":"string","nullable":true},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"height":{"type":"integer"},"isCurrency":{"type":"boolean"},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"sublabel":{"type":"string","description":"Secondary title."},"title":{"type":"string","nullable":true},"type":{"type":"string","description":"The widget type this data is for.","enum":["pieChart"]}}},"WidgetDataProcess":{"type":"object","description":"Data of process widgets.","properties":{"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"defaultValues":{"type":"object"},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"processMetaData":{"type":"object","$ref":"#/components/schemas/ProcessMetaData"},"sublabel":{"type":"string","description":"Secondary title."},"type":{"type":"string","description":"The widget type this data is for.","enum":["process"]}}},"WidgetDataQuickSightChart":{"type":"object","description":"Data of quickSightChart widgets.","properties":{"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"name":{"type":"string","nullable":true},"sublabel":{"type":"string","description":"Secondary title."},"type":{"type":"string","description":"The widget type this data is for.","enum":["quickSightChart"]},"url":{"type":"string","nullable":true}}},"WidgetDataRawHTML":{"type":"object","description":"Data of html widgets.","properties":{"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"html":{"type":"string","nullable":true},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"sublabel":{"type":"string","description":"Secondary title."},"text":{"type":"string","description":"Plain text equivalent of html, preserving link text and line breaks."},"title":{"type":"string","nullable":true},"type":{"type":"string","description":"The widget type this data is for.","enum":["html"]}}},"WidgetDataRowBuilder":{"type":"object","description":"Data of rowBuilder widgets.","properties":{"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"defaultValuesForNewRecords":{"type":"object"},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"hiddenValues":{"type":"object"},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"records":{"type":"array"},"sublabel":{"type":"string","description":"Secondary title."},"type":{"type":"string","description":"The widget type this data is for.","enum":["rowBuilder"]}}},"WidgetDataStatistics":{"type":"object","description":"Data of statistics widgets.","properties":{"count":{"type":"number","description":"Numeric statistic displayed by this widget.","nullable":true},"countContext":{"type":"string","nullable":true},"countFontSize":{"type":"string","nullable":true},"countURL":{"type":"string","nullable":true},"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"increaseIsGood":{"type":"boolean"},"isCurrency":{"type":"boolean"},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"percentageAmount":{"type":"number","nullable":true},"percentageLabel":{"type":"string","nullable":true},"percentageURL":{"type":"string","nullable":true},"sublabel":{"type":"string","description":"Secondary title."},"type":{"type":"string","description":"The widget type this data is for.","enum":["statistics"]}}},"WidgetDataStepper":{"type":"object","description":"Data of stepper widgets.","properties":{"activeStep":{"type":"integer"},"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"steps":{"type":"array"},"sublabel":{"type":"string","description":"Secondary title."},"title":{"type":"string","nullable":true},"type":{"type":"string","description":"The widget type this data is for.","enum":["stepper"]}}},"WidgetDataTable":{"type":"object","description":"Data of table widgets.","properties":{"columns":{"type":"array"},"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"fixedHeight":{"type":"number","nullable":true},"fixedStickyLastRow":{"type":"boolean","nullable":true},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"hidePaginationDropdown":{"type":"boolean","nullable":true},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"linkText":{"type":"string","nullable":true},"linkURL":{"type":"string","nullable":true},"noRowsFoundHTML":{"type":"string","nullable":true},"rows":{"type":"array"},"rowsPerPage":{"type":"number","nullable":true},"sublabel":{"type":"string","description":"Secondary title."},"type":{"type":"string","description":"The widget type this data is for.","enum":["table"]}}},"WidgetDataUSMap":{"type":"object","description":"Data of usaMap widgets.","properties":{"csvData":{"type":"array","description":"Rows (each a list of cells) for exporting the widget as CSV.","items":{"type":"array","items":{}}},"dropdownDataList":{"type":"array","description":"Options of each dropdown filter: a list per dropdown of {id, label} objects.","items":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"dropdownDefaultValueList":{"type":"array","description":"Default value of each dropdown filter.","items":{"type":"string"}},"dropdownLabelList":{"type":"array","description":"Labels of the dropdown filters.","items":{"type":"string"}},"dropdownNameList":{"type":"array","description":"Names of the dropdown filters the widget offers (parallel to the other dropdown lists).","items":{"type":"string"}},"dropdownNeedsSelectedText":{"type":"string","description":"Message to show until every dropdown has a value."},"footerHTML":{"type":"string","description":"Footer, as HTML. Non-web clients render it as plain text."},"footerText":{"type":"string","description":"Plain text equivalent of footerHTML, preserving link text and line breaks."},"hasPermission":{"type":"boolean","description":"False when the user may not see this widget's data; show the label and a permission message only."},"height":{"type":"string","nullable":true},"label":{"type":"string","description":"Title of the widget (overrides the metadata label when present)."},"mapMarkerList":{"type":"array"},"sublabel":{"type":"string","description":"Secondary title."},"type":{"type":"string","description":"The widget type this data is for.","enum":["usaMap"]}}},"WidgetResponseV1":{"type":"object","properties":{"widgetData":{"type":"object","description":"Widget data object, whose shape varies by widget type."}}}},"securitySchemes":{"sessionUuidCookie":{"type":"apiKey","name":"sessionUUID","in":"cookie","description":"The session cookie set by POST /qqq/v1/manageSession (web clients)."},"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT or session UUID","description":"`Authorization: Bearer `, where the token is either\n- an OAuth2 access token (a signed JWT) issued by the app's identity provider to the app's client,\n or to its native client (`values.nativeClientId` in GET /qqq/v1/metaData/authentication), for\n example from the device-authorization grant or auth-code + PKCE. It is verified against the\n provider's keys (issuer, audience, expiry, signature) and gives the same user and permissions\n as signing in on the web. When it expires (401), refresh it at the provider and retry; or\n- a session UUID returned by POST /qqq/v1/manageSession, which the server keeps refreshed."},"oauth2":{"type":"oauth2","description":"The app's OAuth2 / OpenID Connect provider. The real endpoints come from the provider's discovery\ndocument: `{values.baseUrl}.well-known/openid-configuration`, with values from\nGET /qqq/v1/metaData/authentication. Native clients use `values.nativeClientId` (a public client)\nwith auth-code + PKCE (loopback or custom-scheme redirect URI registered at the provider) or the\ndevice-authorization grant (`device_authorization_endpoint`, RFC 8628), then send the access token\nas `Authorization: Bearer`.","flows":{"authorizationCode":{"authorizationUrl":"/authorize","tokenUrl":"/token","scopes":{"email":"Email address","offline_access":"A refresh token, to renew the access token without signing in again","openid":"OpenID Connect sign-in","profile":"Name, username and groups (permissions come from the groups)"}}}}}}} \ No newline at end of file +{ + "openapi": "3.0.3", + "info": { + "title": "QQQ Middleware API", + "description": "## Intro\nThis is the definition of the standard API implemented by QQQ Middleware.\n\nDevelopers of QQQ Frontends (e.g., javascript libraries, or native applications) use this API to access\na QQQ Backend server.\n\nAs such, this API itself is not concerned with any of the application-level details of any particular\napplication built using QQQ. Instead, this API is all about the generic endpoints used for any application\nbuilt on QQQ. For example, many endpoints work with a `${table}` path parameter - whose possible values\nare defined by the application - but which are not known to this API.\n\n## Flow\nThe typical flow of a user (as implemented in a frontend that utilizes this API) looks like:\n1. Frontend calls `.../metaData/authentication`, to know what type of authentication provider is used by the backend, and display an appropriate UI to the user for authenticating.\n2. User authenticates in frontend, as required for the authentication provider.\n3. Frontend calls `.../manageSession`, providing authentication details (e.g., an accessToken or other credentials) to the backend.\n4. The response from the `manageSession` call (assuming success), sets the `sessionUUID` Cookie, which should be included in all subsequent requests for authentication.\n5. After the user is authenticated, the frontend calls `.../metaData`, to discover the apps, tables, processes, etc, that the application is made up of (and that the authenticated user has permission to access).\n6. As the user interacts with apps, tables, process, etc, the frontend utilizes the appropriate endpoints as required.\n\n## Client channel\nEvery request should name its client in the `X-QQQ-Client` header: `channel[/detail]`, e.g. `next-ui`, `cli`,\nor `assistant/` (the accepted channels are listed by `GET .../version`; an unknown one is refused with 400).\nThe channel is recorded in audits. It is attribution only: the actor is always the signed-in user, and a channel\nnever grants anything - but some objects are denied to some channels (e.g. the AI assistant can never see its own\nconfiguration, identity and permission administration, audits, API keys or secrets), exactly as if the user had\nno permission for them.\n", + "contact": { + "email": "contact@kingsrook.com" + }, + "version": "1.8.0", + "x-qqq-extensions": [ + { + "name": "esb", + "version": "1.1.0", + "description": "ESB overview, the ESB of tables and processes, and messages and dead letters on destinations.", + "pathPrefix": "/esb", + "operations": [ + "getEsbOverview", + "getEsbTableByTable", + "getEsbProcessByProcess", + "getEsbDeadLettersByTrigger", + "getEsbMessagesByDestination" + ] + }, + { + "name": "health", + "version": "1.1.0", + "description": "Central health summary, components, history and on-demand checks.", + "pathPrefix": "/health", + "operations": [ + "getHealthSummary", + "getHealthComponentsByName", + "getHealthChecksByNameHistory", + "postHealthChecksByNameRun" + ] + }, + { + "name": "alerts", + "version": "1.2.0", + "description": "Alerts inbox and record panel", + "pathPrefix": "/alerts", + "operations": [ + "alertsInboxSummary", + "alertsInbox", + "alertsInboxRead", + "alertsInboxUnread", + "alertsInboxDismiss", + "alertsRecordPanel" + ] + }, + { + "name": "assistant", + "version": "1.6.0", + "description": "QQQ Assistant: conversations, streamed turns, feedback, pending actions and data access explanations", + "pathPrefix": "/assistant", + "operations": [ + "getAssistantConfig", + "getAssistantConversations", + "postAssistantConversations", + "deleteAssistantConversationsById", + "getAssistantConversationsById", + "patchAssistantConversationsById", + "postAssistantConversationsByIdTurns", + "getAssistantTurnsByTurnIdEvents", + "postAssistantTurnsByTurnIdCancel", + "getAssistantTurnsActive", + "postAssistantMessagesByIdFeedback", + "getAssistantActionsById", + "postAssistantActionsByIdConfirm", + "postAssistantActionsByIdReject", + "getAssistantAccess", + "postAssistantClientErrors" + ] + }, + { + "name": "collaboration", + "version": "1.1.0", + "description": "Record collaboration: favorites, recents, attachments, tags, conversations, following, timeline, people and presence", + "pathPrefix": "/qbit/collaboration", + "operations": [ + "deleteQbitCollaborationPresence", + "getQbitCollaborationPresence", + "postQbitCollaborationPresence", + "deleteQbitCollaborationFavorites", + "getQbitCollaborationFavorites", + "putQbitCollaborationFavorites", + "getQbitCollaborationRecents", + "postQbitCollaborationRecents", + "patchQbitCollaborationFavoritesOrder", + "getQbitCollaborationRecordsByTableByPkAttachments", + "postQbitCollaborationRecordsByTableByPkAttachments", + "getQbitCollaborationAttachmentsByIdDownload", + "getQbitCollaborationAttachmentsByIdPreview", + "deleteQbitCollaborationAttachmentsById", + "patchQbitCollaborationAttachmentsById", + "getQbitCollaborationTags", + "postQbitCollaborationTags", + "getQbitCollaborationRecordsByTableByPkTags", + "putQbitCollaborationRecordsByTableByPkTags", + "getQbitCollaborationRecordsByTableByPkComments", + "postQbitCollaborationRecordsByTableByPkComments", + "deleteQbitCollaborationCommentsById", + "patchQbitCollaborationCommentsById", + "postQbitCollaborationCommentsByIdResolve", + "postQbitCollaborationCommentsByIdReopen", + "getQbitCollaborationCommentsByIdHistory", + "getQbitCollaborationMentionsCandidates", + "deleteQbitCollaborationRecordsByTableByPkFollow", + "getQbitCollaborationRecordsByTableByPkFollow", + "putQbitCollaborationRecordsByTableByPkFollow", + "getQbitCollaborationRecordsByTableByPkFollowers", + "getQbitCollaborationRecordsByTableByPkTimeline", + "getQbitCollaborationPeople", + "getQbitCollaborationPeopleByUserId", + "getQbitCollaborationRecordsByTableByPkLink", + "postQbitCollaborationRecordsByTableByPkSharesPreview", + "postQbitCollaborationRecordsByTableByPkShares", + "postQbitCollaborationAccessRequests", + "getQbitCollaborationAccessRequestsMine", + "getQbitCollaborationRecordsByTableByPkTasks", + "postQbitCollaborationRecordsByTableByPkTasks", + "patchQbitCollaborationTasksById", + "getQbitCollaborationTasksMine", + "putQbitCollaborationRecordsByTableByPkAssignment", + "getQbitCollaborationMyWork" + ] + }, + { + "name": "data-analysis", + "version": "1.5.0", + "description": "Profiles, pivots, comparisons, distribution shifts, correlations, scatter samples, crosstabs and anomaly watch previews as the signed-in user.", + "pathPrefix": "/qbit/data-analysis", + "operations": [ + "postQbitDataAnalysisSavedByIdRun", + "getQbitDataAnalysisSaved", + "deleteQbitDataAnalysisSavedByIdStar", + "putQbitDataAnalysisSavedByIdStar", + "postQbitDataAnalysisTablesByTableSql", + "postQbitDataAnalysisExport", + "getQbitDataAnalysisSavedByIdExport", + "getQbitDataAnalysisTablesByTableCapabilities", + "postQbitDataAnalysisTablesByTableColumnProfile", + "postQbitDataAnalysisTablesByTableDistinctValues", + "postQbitDataAnalysisTablesByTableCompare", + "postQbitDataAnalysisTablesByTableShift", + "postQbitDataAnalysisTablesByTableCorrelation", + "postQbitDataAnalysisTablesByTableScatter", + "postQbitDataAnalysisTablesByTableCrosstab", + "postQbitDataAnalysisWatchesByIdPreview", + "postQbitDataAnalysisTablesByTablePivot", + "postQbitDataAnalysisTablesByTableTableProfile", + "postQbitDataAnalysisTablesByTableDuplicates", + "postQbitDataAnalysisRuns", + "getQbitDataAnalysisRunsByRunId" + ] + }, + { + "name": "db-performance", + "version": "1.0.0", + "description": "Database performance, live activity and audited query plans", + "pathPrefix": "/qbit/db-performance", + "operations": [ + "dbPerformanceOverview", + "dbPerformanceActivity", + "dbPerformanceExplain", + "dbPerformanceLookup" + ] + }, + { + "name": "edi", + "version": "1.1.0", + "description": "EDI sandbox and mapper, using the signed-in user's permissions.", + "pathPrefix": "/qbit/edi", + "operations": [ + "getQbitEdiGuidesByGuideIdTree", + "getQbitEdiMapsByMapIdTarget", + "postQbitEdiSandboxPreview", + "postQbitEdiMapsByMapIdValidate" + ] + }, + { + "name": "qa-capture", + "version": "1.0.0", + "description": "QA bug capture: the user's capture capability and QA report creation", + "pathPrefix": "/qbit/qa-capture", + "operations": [ + "qaCaptureCapability", + "qaCaptureReportCreate" + ] + }, + { + "name": "quick-search", + "version": "1.1.0", + "description": "Quick Search administration and suggestions", + "pathPrefix": "/qbit/quick-search", + "operations": [ + "getQuickSearchStatus", + "getQuickSearchSuggestions" + ] + }, + { + "name": "release-notes", + "version": "1.0.0", + "description": "What's new: published release notes and each user's unread count", + "pathPrefix": "/qbit/release-notes", + "operations": [ + "releaseNotesReleases", + "releaseNotesSummary", + "releaseNotesSeen" + ] + }, + { + "name": "secured-data", + "version": "1.1.0", + "description": "Reveal grants and break-glass status", + "pathPrefix": "/qbit/secured-data", + "operations": [ + "postQbitSecuredDataReveal", + "getQbitSecuredDataRevealOptions", + "getQbitSecuredDataStatus" + ] + }, + { + "name": "sql-workbench", + "version": "1.1.0", + "description": "Audited SQL execution and notebooks", + "pathPrefix": "/sql-workbench", + "operations": [ + "sqlWorkbenchGetCapabilities", + "sqlWorkbenchGetSchema", + "sqlWorkbenchExecute", + "sqlWorkbenchExplain", + "sqlWorkbenchGetRows", + "sqlWorkbenchCancelExecution", + "sqlWorkbenchGetHistory", + "sqlWorkbenchListNotebooks", + "sqlWorkbenchCreateNotebook", + "sqlWorkbenchDeleteNotebook", + "sqlWorkbenchGetNotebook", + "sqlWorkbenchUpdateNotebook", + "sqlWorkbenchPublishNotebook", + "sqlWorkbenchDuplicateNotebook", + "sqlWorkbenchListVersions", + "sqlWorkbenchGetVersion", + "sqlWorkbenchRestoreVersion", + "sqlWorkbenchListSnapshots", + "sqlWorkbenchCreateSnapshot", + "sqlWorkbenchDeleteSnapshot", + "sqlWorkbenchExportResult" + ] + } + ] + }, + "servers": [ + { + "description": "The QQQ server that serves this document (paths include /qqq/v1).", + "url": "/" + } + ], + "tags": [ + { + "name": "Authentication" + }, + { + "name": "Bulk Load" + }, + { + "name": "ESB" + }, + { + "name": "General" + }, + { + "name": "Processes" + }, + { + "name": "Reports" + }, + { + "name": "Tables" + }, + { + "name": "Widgets" + }, + { + "name": "Health" + }, + { + "description": "Operations of the alerts extension.", + "name": "alerts" + }, + { + "description": "Operations of the assistant extension.", + "name": "assistant" + }, + { + "description": "Operations of the collaboration extension.", + "name": "collaboration" + }, + { + "description": "Operations of the data-analysis extension.", + "name": "data-analysis" + }, + { + "description": "Operations of the edi extension.", + "name": "edi" + }, + { + "description": "Operations of the quick-search extension.", + "name": "quick-search" + }, + { + "description": "Operations of the release-notes extension.", + "name": "release-notes" + }, + { + "description": "Operations of the secured-data extension.", + "name": "secured-data" + }, + { + "description": "Operations of the sql-workbench extension.", + "name": "sql-workbench" + } + ], + "paths": { + "/qqq/v1/version": { + "get": { + "summary": "Get the UI API version", + "description": "Describes the semantic version of this UI API (MAJOR.MINOR.PATCH, where MAJOR matches the URL\nversion), the optional core features the server supports, and the extensions (modules and qbits)\nregistered on it, each with its own semantic version.\n\nA client should call this first, before authentication, and stop with a clear message when\napiVersion is outside the range it supports. Not secured.", + "operationId": "getVersion", + "tags": [ + "General" + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VersionResponseV1" + }, + "examples": { + "Server with one extension": { + "value": { + "apiVersion": "1.1.0", + "basePath": "/qqq/v1", + "supportedMajorVersions": [ + 1 + ], + "features": [ + "recordSearch", + "tableVariants", + "version" + ], + "extensions": [ + { + "name": "esb", + "version": "1.0.0", + "pathPrefix": "/esb", + "description": "ESB overview, destinations, messages and dead letters" + } + ] + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + } + } + }, + "/qqq/v1/realtime/stream": { + "get": { + "summary": "Open the realtime event stream", + "description": "SSE invalidation hints. Each event has id :, an event name and JSON data. hello identifies the connection; comment pings maintain it. Last-Event-ID replays retained events on the same pod and session, otherwise resync asks clients to refetch. Core event payloads use the Realtime*EventV1 components. job.progress uses RealtimeJobProgressEventV1; an advancing logSeq tells clients to poll the job log. Qbits publish through RealtimeBus with their own event names, such as presence.changed and comment.added, described by RealtimeEventV1. Subscriptions require a separate POST; session-ended closes the stream and channel-revoked removes a subscription.", + "operationId": "openRealtimeStream", + "tags": [ + "General" + ], + "parameters": [ + { + "name": "Last-Event-ID", + "description": "Last received : cursor.", + "required": false, + "in": "header", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Realtime named events and comment heartbeats.", + "content": { + "text/event-stream": { + "schema": { + "$ref": "#/components/schemas/RealtimeEventV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/realtime/subscriptions": { + "post": { + "summary": "Change realtime subscriptions", + "description": "Add or remove record:{table}:{pk}, table:{table}, user:me, or instance channels. Records require a permission-checked GetAction and tables require READ. Refusals give no reason. The connection must belong to the authenticated session; otherwise 404. Active user channels are returned as user:me. Channel limits apply.", + "operationId": "updateRealtimeSubscriptions", + "tags": [ + "General" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "add": { + "type": "array", + "items": { + "type": "string" + } + }, + "connectionId": { + "type": "string" + }, + "remove": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Current subscriptions and refused additions.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RealtimeSubscriptionResponseV1" + } + } + } + }, + "400": { + "description": "Malformed subscription request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Connection not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/metaData/authentication": { + "get": { + "summary": "Get authentication metaData", + "description": "For a frontend to determine which authentication provider or mechanism to use, it should begin its lifecycle\nby requesting this metaData object, and inspecting the `type` property in the response.\n\nNote that this endpoint is not secured, as its purpose is to be called as part of the workflow that results\nin a user being authenticated.", + "operationId": "getAuthenticationMetaData", + "tags": [ + "Authentication" + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationMetaDataResponseV1" + }, + "examples": { + "For FULLY_ANONYMOUS type": { + "value": { + "type": "FULLY_ANONYMOUS", + "name": "anonymous" + } + }, + "For AUTH_0 type": { + "value": { + "type": "AUTH_0", + "name": "auth0", + "values": { + "clientId": "abcdefg1234567", + "baseUrl": "https://myapp.auth0.com/", + "audience": "myapp.mydomain.com" + } + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + } + } + }, + "/qqq/v1/branding/{role}": { + "get": { + "summary": "Get a branding image", + "description": "The image the app declares for a branding role (`logo` or `icon`), from the application's\nstatic overlay, available before sign-in. 404 when the app declares none for the role, or\ndeclares a data: URI or an external URL (those are in `branding` of GET /metaData/authentication).\nSince 1.6.0.", + "operationId": "getBrandingAsset", + "tags": [ + "Authentication" + ], + "parameters": [ + { + "name": "role", + "description": "logo or icon.", + "required": true, + "in": "path", + "schema": { + "type": "string", + "enum": [ + "logo", + "icon" + ] + } + } + ], + "responses": { + "200": { + "description": "The image (png, jpeg, gif, webp, avif, ico or svg).", + "content": { + "image/*": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + } + } + }, + "/qqq/v1/avatars/lookup": { + "post": { + "summary": "Look up users' avatars", + "description": "The avatar URL (GET /avatars/{avatarId}, with its version) of each user id given, for any signed-in user.\nUsers without an avatar are not in the result: draw their initials. At most 200 ids per call. Since 1.8.0.", + "operationId": "lookupAvatars", + "tags": [ + "Authentication" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AvatarLookupRequestV1" + } + } + } + }, + "responses": { + "200": { + "description": "The avatar URLs of the users that have one.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AvatarLookupResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/avatars/{avatarId}": { + "get": { + "summary": "Get an avatar", + "description": "An avatar as a square PNG, by its opaque id, for any signed-in user. 404 when there is none (draw initials).\nAvatar URLs come from POST /avatars/lookup (other users), `values.user.avatarUrl` of POST /manageSession and\nthe `profile` preferences section (the signed-in user). A user's chosen Gravatar is fetched and re-encoded by\nthe server, so browsers never contact Gravatar. With `v` equal to the current version the response is\ncacheable for a year; otherwise for five minutes, with an ETag. Since 1.8.0.", + "operationId": "getAvatar", + "tags": [ + "Authentication" + ], + "parameters": [ + { + "name": "avatarId", + "description": "The avatar's opaque id (from an avatar URL).", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "size", + "description": "Edge in pixels: 32, 64, 128 or 256 (default 128).", + "required": false, + "in": "query", + "schema": { + "type": "integer" + } + }, + { + "name": "v", + "description": "The avatar's version, from an avatarUrl; makes the response cacheable for a year.", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "The avatar (PNG).", + "content": { + "image/png": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "304": { + "description": "Not modified (If-None-Match matched the ETag)." + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/manageSession": { + "post": { + "summary": "Create a session", + "description": "After a frontend authenticates the user as per the requirements of the authentication provider specified by the\n`type` field in the `metaData/authentication` response, data from that authentication provider should be posted\nto this endpoint, to create a session within the QQQ application.\n\nThe response object will include a session identifier (`uuid`) to authenticate the user in subsequent API calls.\n\nFor the `TABLE_BASED` type, send the user's credentials in an `Authorization: Basic` header (base64 of\n`username:password`, UTF-8); the body may be empty. The password is verified against the user table and a\nsession row is stored; a `401` response means the credentials were refused.\n\nTo resume the session the browser already holds (for example after a page reload), post an empty object:\na request with no credentials and no `sessionUUID` resumes the session named by the `sessionUUID` cookie,\nwhich may be `HttpOnly`. That response carries the session's `values` but not its `uuid`; a `401`\nresponse means there is no valid session to resume.", + "operationId": "manageSession", + "tags": [ + "Authentication" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "description": "Data required to create the session. Specific needs may vary based on the AuthenticationModule type in the QQQ Backend.", + "properties": { + "accessToken": { + "type": "string", + "description": "An access token from a downstream authentication provider (e.g., Auth0), to use as the basis for authentication and authorization." + }, + "code": { + "type": "string", + "description": "OAuth2 authorization code, for the backend to exchange with the identity provider (authorization-code + PKCE sign-in)." + }, + "codeVerifier": { + "type": "string", + "description": "PKCE code verifier that goes with `code`." + }, + "redirectUri": { + "type": "string", + "description": "Redirect URI the authorization `code` was issued to." + }, + "sessionUUID": { + "type": "string", + "description": "UUID of an existing session, to resume it instead of signing in again. Omit it (and all credentials) to resume the session named by the sessionUUID cookie." + } + } + } + } + } + }, + "parameters": [ + { + "name": "Authorization", + "description": "For `TABLE_BASED` authentication: `Basic ` followed by the base64 encoding of `username:password` (UTF-8).\nNot used by other authentication types.", + "in": "header", + "schema": { + "type": "string" + }, + "example": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" + } + ], + "responses": { + "200": { + "description": "Successful response - session has been created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ManageSessionResponseV1" + }, + "examples": { + "With no custom values": { + "value": { + "uuid": "01234567-89AB-CDEF-0123-456789ABCDEF" + } + }, + "With custom values": { + "value": { + "uuid": "98765432-10FE-DCBA-9876-543210FEDCBA", + "values": { + "region": "US", + "userCategoryId": 47 + } + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Authentication error - session was not created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + }, + "examples": { + "Invalid token": { + "value": { + "error": "Unable to decode access token.", + "message": "Unable to decode access token." + } + } + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + } + } + }, + "/qqq/v1/logout": { + "post": { + "summary": "Logout and invalidate session", + "description": "Invalidates the current session server-side, deleting it from the session store\nand clearing any cached data. The session cookie is also removed.\n\nFrontends should call this endpoint before performing client-side logout\n(clearing localStorage, redirecting to IdP logout, etc.) to ensure the\nsession cannot be resumed.", + "operationId": "logout", + "tags": [ + "Authentication" + ], + "responses": { + "200": { + "description": "Session has been invalidated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LogoutResponseV1" + }, + "examples": { + "Successful logout": {} + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + } + } + }, + "/qqq/v1/oidc/backchannel-logout": { + "post": { + "summary": "OIDC Back-Channel Logout", + "description": "Receives logout notifications from the Identity Provider (IdP) when a user\nlogs out from the IdP or another application in the SSO ecosystem.\n\nThe IdP sends a POST request with a 'logout_token' JWT parameter containing\neither a 'sub' (subject) or 'sid' (session ID) claim. QQQ validates the RS256\nsignature against the configured OAuth2 provider's discovered JWKS, issuer,\nclient audience, logout event and timestamps before deleting matching sessions\nfrom the configured session table. Both subject and session ID must match when\nboth are present. Invalid tokens or unsupported configuration return HTTP 400.\n\nThis endpoint should be registered with your IdP as the back-channel logout URI.", + "operationId": "oidcBackChannelLogout", + "tags": [ + "Authentication" + ], + "responses": { + "200": { + "description": "Back-channel logout processed successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackChannelLogoutResponseV1" + }, + "examples": { + "Successful logout": {} + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + } + } + }, + "/qqq/v1/metaData": { + "get": { + "summary": "Get instance metaData", + "description": "Load the overall metadata, as is relevant to a frontend, for the entire application, with permissions applied, as per the\nauthenticated user.\n\nThis includes:\n- Apps (both as a map of name to AppMetaData (`apps`), but also as a tree (`appTree`), for presenting\nhierarchical navigation),\n- Tables (but without all details, e.g., fields),\n- Processes (also without full details, e.g., screens),\n- Reports\n- Widgets\n- Branding\n- Help Contents\n- Environment values\n", + "operationId": "getMetaData", + "tags": [ + "General" + ], + "parameters": [ + { + "name": "frontendName", + "description": "Name of the frontend requesting the meta-data.\nGenerally a QQQ frontend library, unless a custom application frontend has been built.", + "in": "query", + "schema": { + "type": "string" + }, + "example": "qqq-frontend-material-dashboard" + }, + { + "name": "frontendVersion", + "description": "Version of the frontend requesting the meta-data.", + "in": "query", + "schema": { + "type": "string" + }, + "example": "0.23.0" + }, + { + "name": "applicationName", + "description": "Name of the application requesting the meta-data. e.g., an instance of a specific frontend\n(i.e., an application might be deployed with 2 different qqq-frontend-material-dashboard frontends,\nin which case this attribute allows differentiation between them).", + "in": "query", + "schema": { + "type": "string" + }, + "example": "my-admin-web-app" + }, + { + "name": "applicationVersion", + "description": "Version of the application requesting the meta-data.", + "in": "query", + "schema": { + "type": "string" + }, + "example": "20241021" + } + ], + "responses": { + "200": { + "description": "Overall metadata for the application.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetaDataResponseV1" + }, + "examples": { + "Example": { + "value": { + "metaDataGeneration": 0, + "apps": { + "homeApp": { + "label": "Home App", + "sections": [ + { + "role": "PRIMARY", + "label": "Home App", + "tables": [ + "person" + ], + "icon": { + "name": "badge" + }, + "collapsedByDefault": false, + "name": "homeApp" + } + ], + "icon": { + "semanticName": "home", + "name": "home" + }, + "childMap": { + "person": { + "label": "Person", + "icon": { + "name": "person_outline" + }, + "name": "person", + "type": "TABLE" + }, + "childApp": { + "label": "Child App", + "icon": { + "name": "child_friendly" + }, + "name": "childApp", + "type": "APP" + } + }, + "name": "homeApp", + "children": [ + { + "label": "Child App", + "icon": { + "name": "child_friendly" + }, + "name": "childApp", + "type": "APP" + }, + { + "label": "Person", + "icon": { + "name": "person_outline" + }, + "name": "person", + "type": "TABLE" + } + ] + }, + "childApp": { + "label": "Child App", + "sections": [ + { + "role": "PRIMARY", + "label": "Child App", + "processes": [ + "samplePersonProcess" + ], + "icon": { + "name": "badge" + }, + "collapsedByDefault": false, + "name": "childApp" + } + ], + "icon": { + "name": "child_friendly" + }, + "childMap": { + "samplePersonProcess": { + "label": "Sample Person Process", + "icon": { + "semanticName": "person-add", + "name": "person_add" + }, + "name": "samplePersonProcess", + "type": "PROCESS" + } + }, + "name": "childApp", + "children": [ + { + "label": "Sample Person Process", + "icon": { + "semanticName": "person-add", + "name": "person_add" + }, + "name": "samplePersonProcess", + "type": "PROCESS" + } + ] + } + }, + "appTree": [ + { + "label": "Home App", + "icon": { + "semanticName": "home", + "name": "home" + }, + "name": "homeApp", + "type": "APP", + "children": [ + { + "label": "Child App", + "icon": { + "name": "child_friendly" + }, + "name": "childApp", + "type": "APP", + "children": [ + { + "label": "Sample Person Process", + "icon": { + "semanticName": "person-add", + "name": "person_add" + }, + "name": "samplePersonProcess", + "type": "PROCESS" + } + ] + }, + { + "label": "Person", + "icon": { + "name": "person_outline" + }, + "name": "person", + "type": "TABLE" + } + ] + } + ], + "tables": { + "person": { + "label": "Person", + "metaDataGeneration": 0, + "icon": { + "name": "person_outline" + }, + "isHidden": false, + "capabilities": [ + "TABLE_COUNT", + "TABLE_GET", + "TABLE_QUERY", + "QUERY_STATS", + "TABLE_INSERT", + "TABLE_UPDATE", + "TABLE_DELETE", + "TABLE_EXPORT" + ], + "readPermission": true, + "insertPermission": true, + "editPermission": true, + "deletePermission": true, + "name": "person" + } + }, + "processes": { + "person.bulkInsert": { + "label": "Person Bulk Insert", + "stepFlow": "LINEAR", + "iconName": "library_add", + "tableName": "person", + "icon": { + "semanticName": "library-add", + "name": "library_add" + }, + "isHidden": true, + "hasPermission": true, + "durableJobEligible": false, + "durableJobAlways": false, + "iconSemanticName": "library-add", + "name": "person.bulkInsert" + }, + "person.bulkEdit": { + "label": "Person Bulk Edit", + "stepFlow": "LINEAR", + "tableName": "person", + "isHidden": true, + "hasPermission": true, + "durableJobEligible": false, + "durableJobAlways": false, + "name": "person.bulkEdit" + }, + "samplePersonProcess": { + "label": "Sample Person Process", + "stepFlow": "LINEAR", + "iconName": "person_add", + "tableName": "person", + "icon": { + "semanticName": "person-add", + "name": "person_add" + }, + "isHidden": false, + "hasPermission": true, + "durableJobEligible": false, + "durableJobAlways": false, + "iconSemanticName": "person-add", + "name": "samplePersonProcess" + }, + "person.bulkDelete": { + "label": "Person Bulk Delete", + "stepFlow": "LINEAR", + "tableName": "person", + "isHidden": true, + "hasPermission": true, + "durableJobEligible": false, + "durableJobAlways": false, + "name": "person.bulkDelete" + }, + "person.bulkEditWithFile": { + "label": "Person Bulk Edit With File", + "stepFlow": "LINEAR", + "tableName": "person", + "isHidden": true, + "hasPermission": true, + "durableJobEligible": false, + "durableJobAlways": false, + "name": "person.bulkEditWithFile" + } + } + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/preferences": { + "get": { + "summary": "List visible sections and the signed-in user's preferences", + "description": "Preferences always belong to the authenticated session user. No user identifier is accepted. Unknown or hidden sections return 404; unauthenticated requests return 401. PATCH changes only supplied fields and fixed rows; invalid changes return 400 with all messages before anything is stored. Writes are audited as the user and client channel.", + "operationId": "listPreferenceSections", + "tags": [ + "General" + ], + "responses": { + "200": { + "description": "Current preferences for the session user", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PreferencesResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/delivery/destinations": { + "get": { + "summary": "List authorized output destinations", + "operationId": "listDeliveryDestinations", + "tags": [ + "General" + ], + "responses": { + "200": { + "description": "Delivery response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeliveryDestinationsResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/delivery/destinations/{name}/targets": { + "post": { + "summary": "Describe the next delivery target", + "operationId": "chooseDeliveryTargets", + "tags": [ + "General" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeliveryTargetsRequestV1" + } + } + } + }, + "parameters": [ + { + "name": "name", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Delivery response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeliveryTargetStepResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/delivery/output/{logId}": { + "get": { + "summary": "Download stored output as its owner or delivery administrator", + "operationId": "getDeliveryOutput", + "tags": [ + "General" + ], + "parameters": [ + { + "name": "logId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Stored output; multiple attachments form a ZIP archive", + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/DeliveryOutputResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/preferences/{sectionName}": { + "get": { + "summary": "Read one visible section for the signed-in user", + "description": "Preferences always belong to the authenticated session user. No user identifier is accepted. Unknown or hidden sections return 404; unauthenticated requests return 401. PATCH changes only supplied fields and fixed rows; invalid changes return 400 with all messages before anything is stored. Writes are audited as the user and client channel.", + "operationId": "getPreferenceSection", + "tags": [ + "General" + ], + "parameters": [ + { + "name": "sectionName", + "description": "Registered visible preference section name, from GET /preferences.", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Current preferences for the session user", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PreferenceSectionV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + }, + "patch": { + "summary": "Partially update the signed-in user's preferences", + "description": "Preferences always belong to the authenticated session user. No user identifier is accepted. Unknown or hidden sections return 404; unauthenticated requests return 401. PATCH changes only supplied fields and fixed rows; invalid changes return 400 with all messages before anything is stored. Writes are audited as the user and client channel.", + "operationId": "updatePreferenceSection", + "tags": [ + "General" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PreferenceSectionPatchRequestV1" + } + } + } + }, + "parameters": [ + { + "name": "sectionName", + "description": "Registered visible preference section name, from GET /preferences.", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Current preferences for the session user", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PreferenceSectionV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/preferences/{sectionName}/actions/{actionName}": { + "post": { + "summary": "Run an action on the signed-in user's preferences", + "description": "Runs a registered action for the authenticated session user. ROW actions target only rows loaded for that user and allowed by actionNames. Unknown actions or hidden sections return 404; invalid inputs return 400; unauthenticated requests return 401. Clients must confirm confirmationText before running. Secrets are shown once and must not be stored, logged, cached, or sent to analytics by clients. Responses use Cache-Control: no-store.", + "operationId": "runPreferenceSectionAction", + "tags": [ + "General" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PreferenceActionRequestV1" + } + } + } + }, + "parameters": [ + { + "name": "sectionName", + "description": "Registered visible preference section name, from GET /preferences.", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "actionName", + "description": "Registered action name from the visible section.", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Current preferences for the session user", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PreferenceActionResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/metaData/table/{tableName}": { + "get": { + "summary": "Get table metaData", + "description": "Load the full metadata for a single table, including all fields, which a frontend\nneeds to display to users.", + "operationId": "getTableMetaData", + "tags": [ + "Tables" + ], + "parameters": [ + { + "name": "tableName", + "description": "Name of the table to load.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + } + ], + "responses": { + "200": { + "description": "The full table metadata", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TableMetaDataResponseV1" + }, + "examples": { + "Example": { + "value": { + "tableMetaData": { + "clientCapabilities": { + "savedViews": { + "available": false + }, + "audits": { + "available": false, + "level": "NONE" + }, + "bulkInsert": { + "available": true, + "processName": "person.bulkInsert" + }, + "bulkEdit": { + "available": true, + "processName": "person.bulkEdit" + }, + "bulkEditWithFile": { + "available": true, + "processName": "person.bulkEditWithFile" + }, + "bulkDelete": { + "available": true, + "processName": "person.bulkDelete" + } + }, + "sections": [ + { + "label": "Identity", + "tier": "T1", + "icon": { + "name": "badge" + }, + "fieldNames": [ + "id" + ], + "name": "identity", + "hidden": false + } + ], + "usesVariants": false, + "primaryKeyField": "id", + "hasRestrictedFields": false, + "fields": { + "id": { + "label": "Id", + "isHeavy": false, + "isRequired": false, + "isEditable": true, + "displayFormat": "%s", + "isHidden": false, + "name": "id", + "type": "INTEGER" + } + }, + "label": "Person", + "metaDataGeneration": 0, + "icon": { + "name": "person_outline" + }, + "isHidden": false, + "capabilities": [ + "TABLE_COUNT", + "TABLE_GET", + "TABLE_QUERY", + "QUERY_STATS", + "TABLE_INSERT", + "TABLE_UPDATE", + "TABLE_DELETE", + "TABLE_EXPORT" + ], + "readPermission": true, + "insertPermission": true, + "editPermission": true, + "deletePermission": true, + "name": "person" + } + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/query": { + "post": { + "summary": "Query for records from a table", + "description": "Execute a query against a table, returning records that match a filter.", + "operationId": "queryTable", + "tags": [ + "Tables" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "filter": { + "description": "QueryFilter to specify matching records to be returned by the query", + "$ref": "#/components/schemas/QueryFilter" + }, + "joins": { + "type": "array", + "description": "QueryJoin objects to specify tables to be joined into the query", + "items": { + "$ref": "#/components/schemas/QueryJoin" + } + }, + "tableVariant": { + "description": "For tables that use variant backends, specification of which variant to use.", + "$ref": "#/components/schemas/TableVariant" + } + } + } + } + } + }, + "parameters": [ + { + "name": "tableName", + "description": "Name of the table to query.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + } + ], + "responses": { + "200": { + "description": "The records matching query", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TableQueryResponseV1" + }, + "examples": { + "TODO": { + "value": { + "records": [ + { + "values": { + "id": 17, + "quantity": 1000, + "storeId": 42 + }, + "displayValues": { + "id": "17", + "quantity": "1,000", + "storeId": "QQQ-Mart" + }, + "recordLabel": "Item 17", + "tableName": "item" + } + ] + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/count": { + "post": { + "summary": "Count records in a table", + "description": "Execute a query against a table, returning the number of records that match a filter.", + "operationId": "countTable", + "tags": [ + "Tables" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "filter": { + "description": "QueryFilter to specify matching records to be returned by the query", + "$ref": "#/components/schemas/QueryFilter" + }, + "joins": { + "type": "array", + "description": "QueryJoin objects to specify tables to be joined into the query", + "items": { + "$ref": "#/components/schemas/QueryJoin" + } + }, + "tableVariant": { + "description": "For tables that use variant backends, specification of which variant to use.", + "$ref": "#/components/schemas/TableVariant" + } + } + } + } + } + }, + "parameters": [ + { + "name": "tableName", + "description": "Name of the table to count.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + }, + { + "name": "includeDistinct", + "description": "Whether or not to also return the count distinct records from the main table (e.g., in case of a to-many join; by default, do not).", + "required": true, + "in": "query", + "schema": { + "type": "boolean" + }, + "example": "true" + } + ], + "responses": { + "200": { + "description": "The number (count) of records matching the query", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TableCountResponseV1" + }, + "examples": { + "TODO": { + "value": { + "count": 42 + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/search": { + "post": { + "summary": "Search records across tables", + "description": "Search for records whose search fields (declared per table in its meta-data, and listed as `searchFields` in the\ntable meta-data) match a search term. String fields match when they contain the term, ignoring case; integer\nfields match when they equal a numeric term. Only tables that the user has permission to read are searched,\nrecord security locks apply, and each table returns at most `limitPerTable` records (default 5, maximum 25), after skipping `offset` matches in each table (for paging one table). An instance may have a record search\nprovider (e.g., a search index) that searches some tables instead; if it fails, those tables are searched with\nthe default search, and the response's `provider` and `tables` say so.\n\nEach result can carry plain-text `highlights` of the fields that match (with the matched spans as character\noffsets - never markup), `details` (other search field values), `updatedAt` and, from a provider, a `score`.\nOnly fields the user may see are used. All of these, and `tables` and `provider`, are optional: clients must\ntolerate their absence.", + "operationId": "searchRecords", + "tags": [ + "Tables" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "searchTerm": { + "type": "string", + "description": "Text to search for (required; at most 100 characters after trimming).", + "example": "Kelkhoff" + }, + "tableNames": { + "type": "array", + "description": "Optional list of table names to search. When omitted or empty, every table with search fields is searched.", + "items": { + "type": "string" + } + }, + "limitPerTable": { + "type": "number", + "description": "Maximum number of records to return from each table." + }, + "offset": { + "type": "number", + "description": "Number of matches to skip in each table, for paging (default 0, maximum 1000). Mainly useful with one table in tableNames." + }, + "sort": { + "type": "string", + "description": "Order of the results within each table: RELEVANCE (default) or RECENT (most recently modified first, for tables with a last-modified field).", + "enum": [ + "RELEVANCE", + "RECENT" + ] + } + } + } + } + } + }, + "responses": { + "200": { + "description": "The records matching the search term", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordSearchResponseV1" + }, + "examples": { + "Matches in one table": { + "value": { + "results": [ + { + "recordLabel": "Darin Kelkhoff", + "details": [ + { + "displayValue": "Saint Louis", + "fieldLabel": "City", + "fieldName": "city" + } + ], + "tableName": "person", + "recordId": "1", + "tableLabel": "Person", + "score": 7.25, + "updatedAt": "2026-10-01T14:30:00Z", + "highlights": [ + { + "matches": [ + { + "end": 14, + "start": 6 + } + ], + "fieldLabel": "Email", + "text": "darin.kelkhoff@example.com", + "fieldName": "email" + } + ] + }, + { + "recordLabel": "Tim Kelkhoff", + "tableName": "person", + "recordId": "2", + "tableLabel": "Person", + "score": 6.5 + } + ], + "tables": [ + { + "totalCount": 14, + "tableName": "person", + "tableLabel": "Person", + "resultCount": 2, + "hasMore": true, + "source": "PROVIDER" + } + ], + "provider": { + "status": "OK" + } + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/help/search": { + "get": { + "summary": "Search visible application help", + "description": "Search help visible to the session. Label hits weigh 3, summary hits 2 and content hits 1. Stable ties sort by kind and key. Limit defaults to 20 and is capped at 50.", + "operationId": "searchHelp", + "tags": [ + "General" + ], + "parameters": [ + { + "name": "q", + "required": true, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "required": false, + "in": "query", + "schema": { + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "Help search results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HelpSearchResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/help/coverage": { + "get": { + "summary": "Inspect application help coverage", + "description": "Requires INSERT or EDIT permission on helpContent. Includes hidden targets. Totals reflect kind and parent scope before missingOnly is applied.", + "operationId": "getHelpCoverage", + "tags": [ + "General" + ], + "parameters": [ + { + "name": "kind", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "missingOnly", + "required": false, + "in": "query", + "schema": { + "type": "boolean" + } + }, + { + "name": "parentKey", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Help coverage results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HelpCoverageResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "No INSERT or EDIT permission on helpContent", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/variants": { + "get": { + "summary": "List a table's backend variants", + "description": "List the variants a table's backend can be scoped to (for example one data set per store). Requires read\npermission on the table and on the backend's variant options table.", + "operationId": "listTableVariants", + "tags": [ + "Tables" + ], + "parameters": [ + { + "name": "tableName", + "description": "Name of the table whose variants to list.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + } + ], + "responses": { + "200": { + "description": "The variants the table can be scoped to.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TableVariantsResponseV1" + }, + "examples": { + "A table with variants": { + "value": { + "variants": [ + { + "type": "store", + "id": "1", + "name": "Main Street" + } + ] + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/apis": { + "get": { + "summary": "List the APIs that expose a table", + "description": "The application APIs (served by the API middleware beside this one) that expose the table, with each API's versions and the root-relative path of the table's OpenAPI document in each version. Empty when the application serves no APIs. The caller must be allowed to read the table.", + "operationId": "listTableApis", + "tags": [ + "Tables" + ], + "parameters": [ + { + "name": "tableName", + "description": "Name of the table.", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TableApisResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/{primaryKey}": { + "get": { + "summary": "Get a record from a table by primary key", + "description": "Fetch a single record from a table, identified by its primary key value.", + "operationId": "getRecord", + "tags": [ + "Tables" + ], + "parameters": [ + { + "name": "tableName", + "description": "Name of the table to get the record from.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + }, + { + "name": "primaryKey", + "description": "Primary key value of the record to get.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "42" + }, + { + "name": "includeAssociations", + "description": "Whether or not to include associated records.", + "required": false, + "in": "query", + "schema": { + "type": "boolean" + }, + "example": "true" + }, + { + "name": "queryJoins", + "description": "JSON array of QueryJoin objects specifying tables to join into the get.", + "required": false, + "in": "query", + "schema": { + "type": "string" + }, + "example": "[{\"joinTable\":\"orderLine\",\"select\":true}]" + }, + { + "name": "tableVariant", + "description": "For tables that use variant backends, JSON object naming the variant to read from (the same `type` and `id` as in query requests).", + "required": false, + "in": "query", + "schema": { + "type": "string" + }, + "example": "{\"type\":\"store\",\"id\":\"1\"}" + } + ], + "responses": { + "200": { + "description": "The record matching the given primary key", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TableGetResponseV1" + }, + "examples": { + "TODO": { + "value": { + "record": { + "values": { + "id": 1, + "firstName": "Darin", + "lastName": "Kelkhoff" + }, + "displayValues": { + "id": "1", + "firstName": "Darin", + "lastName": "Kelkhoff" + }, + "recordLabel": "Darin Kelkhoff", + "tableName": "person" + } + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + }, + "patch": { + "summary": "Update a record in a table", + "description": "Update an existing record in a table, identified by its primary key. The request body should contain the field values to update.", + "operationId": "updateRecord", + "tags": [ + "Tables" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "description": "JSON object with field names as keys and field values as values.", + "properties": { + "fieldName": { + "type": "string", + "description": "Value for a field in the record. Repeat for each field to update." + } + } + } + }, + "multipart/form-data": { + "schema": { + "type": "object", + "description": "Form fields named for the record's fields (an empty field clears the value), a file for each blob field to set, and optionally an `associations` field: JSON of association name to a list of associated records. With the request header `X-QQQ-Association-Format: record-v1`, each associated record is `{\"values\": {...}, \"associations\": {...}}`, nested to any depth, and exactly one `associations` field is required.", + "properties": { + "fieldName": { + "type": "string", + "description": "Value for a field in the record. Repeat for each field to set." + }, + "associations": { + "type": "string", + "description": "JSON object of association name to a list of associated records." + } + } + } + } + } + }, + "parameters": [ + { + "name": "expectedVersion", + "description": "Optional optimistic version from the last read, encoded as a string in the version field's format (ISO-8601 for modify dates). A mismatch returns 409 RecordConflictV1 and leaves the record unchanged. Omit for an unconditional update. Tables with recordVersionField set to an empty string opt out.", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "tableName", + "description": "Name of the table containing the record to update.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + }, + { + "name": "primaryKey", + "description": "Primary key value of the record to update.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "42" + } + ], + "responses": { + "200": { + "description": "The record that was updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TableUpdateResponseV1" + }, + "examples": { + "TODO": { + "value": { + "record": { + "values": { + "id": 1, + "firstName": "Darin", + "lastName": "Kelkhoff" + }, + "displayValues": { + "id": "1", + "firstName": "Darin", + "lastName": "Kelkhoff" + }, + "recordLabel": "Darin Kelkhoff", + "tableName": "person" + } + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "The record changed since it was read.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordConflictV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + }, + "delete": { + "summary": "Delete a record from a table", + "description": "Delete a single record from a table, identified by its primary key value.", + "operationId": "deleteRecord", + "tags": [ + "Tables" + ], + "parameters": [ + { + "name": "tableName", + "description": "Name of the table to delete from.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + }, + { + "name": "primaryKey", + "description": "Primary key value of the record to delete.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "42" + } + ], + "responses": { + "200": { + "description": "The number of records that were deleted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TableDeleteResponseV1" + }, + "examples": { + "TODO": { + "value": { + "deletedRecordCount": 1 + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/{primaryKey}/features": { + "get": { + "summary": "Get record collaboration features", + "description": "Features and capabilities for a visible record, with optional summary provider contributions.", + "operationId": "getRecordFeatures", + "tags": [ + "Tables" + ], + "parameters": [ + { + "name": "tableName", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "primaryKey", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Record collaboration summary", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordFeatureSummaryV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/formAdjuster/{identifier}/{event}": { + "post": { + "summary": "Run a form adjuster", + "description": "Run one of a table form's adjusters and return the changes to apply to the form. The identifier is `table:{tableName}` for the table's on-load adjuster, or a field's `formAdjusterIdentifier` (from its `materialDashboard` supplemental metadata) for that field's adjusters. The caller must be allowed to insert or edit records in the table. Answers 404 when the application registers no form adjusters.", + "operationId": "runFormAdjuster", + "tags": [ + "Tables" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "description": "The form's state when the event fired.", + "properties": { + "fieldName": { + "type": "string", + "description": "The field the event is for (field adjusters)." + }, + "newValue": { + "description": "The field's new value (field adjusters); sent to the adjuster as text." + }, + "allValues": { + "type": "object", + "description": "Every value of the form, by field name.", + "additionalProperties": true + } + } + } + } + } + }, + "parameters": [ + { + "name": "tableName", + "description": "Name of the table whose form is being adjusted.", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "identifier", + "description": "`table:{tableName}`, or a field's `formAdjusterIdentifier`.", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "event", + "description": "Which adjuster to run.", + "required": true, + "in": "path", + "schema": { + "type": "string", + "enum": [ + "onLoad", + "onChange" + ] + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FormAdjusterOutputV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/apis/{apiName}/{version}/openapi": { + "get": { + "summary": "Get a table's OpenAPI document in an application API", + "description": "The OpenAPI 3 document of the table in one version of an application API that exposes it (as listed by `GET /table/{tableName}/apis`). The caller must be allowed to read the table. Answers 404 when no API by that name exposes the table in that version.", + "operationId": "getTableApiDocument", + "tags": [ + "Tables" + ], + "parameters": [ + { + "name": "tableName", + "description": "Name of the table.", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "apiName", + "description": "The API's name (`name` in `GET /table/{tableName}/apis`).", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "version", + "description": "The API version (`versions[].version`).", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TableApiDocumentV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}": { + "post": { + "summary": "Insert a record into a table", + "description": "Insert a new record into a table. The request body should contain the field values for the new record.", + "operationId": "insertRecord", + "tags": [ + "Tables" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "description": "JSON object with field names as keys and field values as values.", + "properties": { + "fieldName": { + "type": "string", + "description": "Value for a field in the record. Repeat for each field to set." + } + } + } + }, + "multipart/form-data": { + "schema": { + "type": "object", + "description": "Form fields named for the record's fields (an empty field clears the value), a file for each blob field to set, and optionally an `associations` field: JSON of association name to a list of associated records. With the request header `X-QQQ-Association-Format: record-v1`, each associated record is `{\"values\": {...}, \"associations\": {...}}`, nested to any depth, and exactly one `associations` field is required.", + "properties": { + "fieldName": { + "type": "string", + "description": "Value for a field in the record. Repeat for each field to set." + }, + "associations": { + "type": "string", + "description": "JSON object of association name to a list of associated records." + } + } + } + } + } + }, + "parameters": [ + { + "name": "tableName", + "description": "Name of the table to insert into.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + } + ], + "responses": { + "200": { + "description": "The record that was inserted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TableInsertResponseV1" + }, + "examples": { + "TODO": { + "value": { + "record": { + "values": { + "id": 47, + "firstName": "New", + "lastName": "Person" + }, + "displayValues": { + "id": "47", + "firstName": "New", + "lastName": "Person" + }, + "recordLabel": "New Person", + "tableName": "person" + } + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/relatedRecordPicker/{pickerName}/query": { + "post": { + "summary": "Query the records a related-record picker offers", + "description": "Lists one page of the picker's target records as the user may read them: the user's filter (the target table's own filter builder or a saved view), ANDed with the picker's filter (resolved from the parent record or form values) and the search term. Needs READ on the target table; table permissions, record security locks and field security locks apply as on the table query route. Reads limit + 1 rows for hasMore (no count). For MULTI_CHILD and LINK with a primaryKey, linkedIds says which returned records the parent already has rows for.", + "operationId": "queryRelatedRecordPicker", + "tags": [ + "Tables" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "primaryKey": { + "type": "string", + "description": "Primary key of the parent record (required for MULTI_CHILD and LINK; for SINGLE, the record being edited, if any). Read with the user's own security." + }, + "values": { + "type": "object", + "description": "Current form values (SINGLE on a create form, when there is no primaryKey), for ${input.fieldName} variables in the picker's filters" + }, + "searchTerm": { + "type": "string", + "description": "Case-insensitive text matched (contains) against the target table's search fields, or its record-label fields" + }, + "filter": { + "description": "The user's filter on the target table (criteria and orderBys on target fields only); ANDed with the picker's filter", + "$ref": "#/components/schemas/QueryFilter" + }, + "skip": { + "type": "integer", + "description": "Records to skip (offset paging)" + }, + "limit": { + "type": "integer", + "description": "Records per page, 1 to 200 (default 50)" + } + } + } + } + } + }, + "parameters": [ + { + "name": "tableName", + "description": "Name of the table that declares the picker (e.g. the order).", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "sales_order" + }, + { + "name": "pickerName", + "description": "Name of the picker, from the table metadata's relatedRecordPickers.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "addSkus" + } + ], + "responses": { + "200": { + "description": "Query the records a related-record picker offers: result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RelatedRecordPickerQueryResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/relatedRecordPicker/{pickerName}/prepare": { + "post": { + "summary": "Prepare child rows for picked records (MULTI_CHILD, LINK)", + "description": "Builds, without saving, one child row per picked target: the picker's child field defaults, values copied from the target, and the parent and target keys. The client shows the reviewFieldNames of each row for the user to fill, then calls add. Needs INSERT on the child table; every target must be available through the picker's query (else 400).", + "operationId": "prepareRelatedRecordPicker", + "tags": [ + "Tables" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "primaryKey": { + "type": "string", + "description": "Primary key of the parent record. Read with the user's own security." + }, + "targetIds": { + "type": "array", + "description": "Primary keys of the picked target records", + "items": { + "type": "string" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "tableName", + "description": "Name of the table that declares the picker (e.g. the order).", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "sales_order" + }, + { + "name": "pickerName", + "description": "Name of the picker, from the table metadata's relatedRecordPickers.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "addSkus" + } + ], + "responses": { + "200": { + "description": "Prepare child rows for picked records (MULTI_CHILD, LINK): result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RelatedRecordPickerPrepareResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/relatedRecordPicker/{pickerName}/add": { + "post": { + "summary": "Add child or join rows for picked records (MULTI_CHILD, LINK)", + "description": "Inserts one row per picked target (targetIds) or per reviewed row (records), all or nothing, through the standard insert action: INSERT permission on the child table, record security locks, validation, customizers, automations and audit. Only the picker's review fields are taken from the client; the parent and target keys always come from the server. Every target must be available through the picker's query (else 400). Row errors are a 400 naming each row, and nothing is saved.", + "operationId": "addRelatedRecords", + "tags": [ + "Tables" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "primaryKey": { + "type": "string", + "description": "Primary key of the parent record. Read with the user's own security." + }, + "targetIds": { + "type": "array", + "description": "Primary keys of the picked target records", + "items": { + "type": "string" + } + }, + "records": { + "type": "array", + "description": "Reviewed child rows (instead of targetIds), e.g. the prepare route's rows after the user filled the review fields", + "items": { + "type": "object", + "properties": { + "values": { + "type": "object", + "description": "The row's values: the childTargetFieldName (which target) and the picker's reviewFieldNames; other values are ignored, and the parent and target keys always come from the server" + } + } + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "tableName", + "description": "Name of the table that declares the picker (e.g. the order).", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "sales_order" + }, + { + "name": "pickerName", + "description": "Name of the picker, from the table metadata's relatedRecordPickers.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "addSkus" + } + ], + "responses": { + "200": { + "description": "Add child or join rows for picked records (MULTI_CHILD, LINK): result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RelatedRecordPickerAddResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/relatedRecordPicker/{pickerName}/remove": { + "post": { + "summary": "Unlink picked records (LINK)", + "description": "Deletes the parent's join rows for the given targets through the standard delete action (DELETE permission on the join table, record security locks, audit). Only for LINK pickers (else 400); child rows of a MULTI_CHILD picker are deleted with the table delete route.", + "operationId": "removeRelatedRecords", + "tags": [ + "Tables" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "primaryKey": { + "type": "string", + "description": "Primary key of the parent record. Read with the user's own security." + }, + "targetIds": { + "type": "array", + "description": "Primary keys of the picked target records", + "items": { + "type": "string" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "tableName", + "description": "Name of the table that declares the picker (e.g. the order).", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "sales_order" + }, + { + "name": "pickerName", + "description": "Name of the picker, from the table metadata's relatedRecordPickers.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "addSkus" + } + ], + "responses": { + "200": { + "description": "Unlink picked records (LINK): result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RelatedRecordPickerRemoveResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/{primaryKey}/developer": { + "get": { + "summary": "Get a record's associated scripts (developer mode)", + "description": "Fetch a single record (with display values), along with each of its table's associated scripts:\nthe script type, the script that the record references (if any) with its revisions (newest first),\nand, for scripts that can be tested, the fields to test them with.\n\nRequires permission to read records from the table. If the record is not found, a 404 is returned.", + "operationId": "getRecordDeveloperMode", + "tags": [ + "Tables" + ], + "parameters": [ + { + "name": "tableName", + "description": "Name of the table that the record is in.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + }, + { + "name": "primaryKey", + "description": "Primary key value of the record.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "42" + } + ], + "responses": { + "200": { + "description": "The record, with its table's associated scripts", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordDeveloperModeResponseV1" + }, + "examples": { + "TODO": { + "value": { + "record": { + "values": { + "id": 1, + "firstName": "Darin", + "greetingScriptId": 7 + }, + "displayValues": { + "id": "1", + "firstName": "Darin", + "greetingScriptId": "7" + }, + "recordLabel": "Darin Kelkhoff", + "tableName": "person" + }, + "associatedScripts": [ + { + "associatedScript": { + "scriptTypeId": 1, + "fieldName": "greetingScriptId" + }, + "scriptRevisions": [ + { + "values": { + "id": 12, + "scriptId": 7, + "sequenceNo": 2, + "commitMessage": "Say hello by name" + }, + "tableName": "scriptRevision" + } + ], + "testInputFields": [ + { + "label": "Name", + "isHeavy": false, + "isRequired": false, + "isEditable": true, + "displayFormat": "%s", + "isHidden": false, + "name": "name", + "type": "STRING" + } + ], + "testOutputFields": [ + { + "label": "Message", + "isHeavy": false, + "isRequired": false, + "isEditable": true, + "displayFormat": "%s", + "isHidden": false, + "name": "message", + "type": "STRING" + } + ], + "scriptType": { + "values": { + "id": 1, + "name": "Greeting" + }, + "recordLabel": "Greeting", + "tableName": "scriptType" + }, + "script": { + "values": { + "id": 7, + "name": "Darin Kelkhoff - Greeting", + "scriptTypeId": 1, + "currentScriptRevisionId": 12 + }, + "recordLabel": "Darin Kelkhoff - Greeting", + "tableName": "script" + } + } + ] + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/{primaryKey}/developer/panels": { + "get": { + "summary": "Get a record's developer panels", + "description": "Fetch the panels shown on a record's developer view: one per developer panel provider (built in, or\nregistered by modules and qbits in the instance's developerPanels supplemental meta-data) that is available\nfor this table and record for the current user - for example record security, ESB events, quick search\nindexing, or SQL workbench queries.\n\nRequires permission to read records from the table, and the record must be visible under its record\nsecurity locks. If the record is not found, a 404 is returned. A provider that fails yields a panel\nwith an error message rather than failing the request.", + "operationId": "listRecordDeveloperPanels", + "tags": [ + "Tables" + ], + "parameters": [ + { + "name": "tableName", + "description": "Name of the table that the record is in.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + }, + { + "name": "primaryKey", + "description": "Primary key value of the record.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "42" + } + ], + "responses": { + "200": { + "description": "The record's developer panels", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordDeveloperPanelsResponseV1" + }, + "examples": { + "Record security": { + "value": { + "panels": [ + { + "id": "recordSecurity", + "title": "Record Security", + "order": 150, + "statusLabel": "1 lock", + "statusTone": "SUCCESS", + "blocks": [ + { + "type": "TABLE", + "label": "Locks", + "columns": [ + "Security key", + "Field", + "Scope", + "Null values", + "This record's value", + "Your access" + ], + "rows": [ + [ + "store", + "storeId", + "READ_AND_WRITE", + "DENY", + "42", + "Your session has key value 42" + ] + ] + } + ] + } + ] + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/{primaryKey}/developer/associatedScript/{fieldName}": { + "post": { + "summary": "Store a new revision of a record's associated script (developer mode)", + "description": "Save new contents for the script that a record references in one of its table's associated script\nfields, as a new revision of that script. If the record does not yet reference a script, one is\ninserted (and the record is updated to reference it).\n\nRequires permission to edit records in the table.", + "operationId": "storeAssociatedScript", + "tags": [ + "Tables" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "contents": { + "type": "string", + "description": "The script's new contents (its code).", + "example": "return (\"Hello, \" + input.getName());" + }, + "commitMessage": { + "type": "string", + "description": "A message describing the change. If not given, a default message is used.", + "example": "Say hello by name" + } + } + } + } + } + }, + "parameters": [ + { + "name": "tableName", + "description": "Name of the table that the record is in.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + }, + { + "name": "primaryKey", + "description": "Primary key value of the record.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "42" + }, + { + "name": "fieldName", + "description": "Name of the associated script field (in the table) whose script is being stored.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "greetingScriptId" + } + ], + "responses": { + "200": { + "description": "The script, and the revision that was stored", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordAssociatedScriptStoreResponseV1" + }, + "examples": { + "TODO": { + "value": { + "scriptId": 7, + "scriptName": "Darin Kelkhoff - Greeting", + "scriptRevisionId": 13, + "scriptRevisionSequenceNo": 3 + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/{primaryKey}/developer/associatedScript/{fieldName}/{scriptRevisionId}/logs": { + "get": { + "summary": "Get the logs of a record's associated script revision (developer mode)", + "description": "Fetch the logs (up to 100, newest first) of runs of a script revision, each with its log lines.\n\nRequires permission to read records from the table, and the record must exist (else a 404 is returned).", + "operationId": "getAssociatedScriptLogs", + "tags": [ + "Tables" + ], + "parameters": [ + { + "name": "tableName", + "description": "Name of the table that the record is in.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + }, + { + "name": "primaryKey", + "description": "Primary key value of the record.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "42" + }, + { + "name": "fieldName", + "description": "Name of the associated script field (in the table) whose script the revision is of.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "greetingScriptId" + }, + { + "name": "scriptRevisionId", + "description": "Id of the script revision to get logs for.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "12" + } + ], + "responses": { + "200": { + "description": "The script revision's logs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordAssociatedScriptLogsResponseV1" + }, + "examples": { + "TODO": { + "value": { + "scriptLogRecords": [ + { + "values": { + "id": 101, + "scriptRevisionId": 12, + "startTimestamp": "2024-10-21T14:30:00Z", + "hadError": false, + "scriptLogLine": [ + { + "tableName": "scriptLogLine", + "values": { + "id": 1001, + "scriptLogId": 101, + "timestamp": "2024-10-21T14:30:00Z", + "text": "Hello, Darin" + } + } + ] + }, + "tableName": "scriptLog" + } + ] + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/possibleValues/{fieldName}": { + "post": { + "summary": "Search possible values for a table field", + "description": "Search for possible values associated with a field on a table.\nReturns a list of id/label pairs that match the given search criteria.", + "operationId": "searchTablePossibleValues", + "tags": [ + "Tables" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "searchTerm": { + "type": "string", + "description": "Text to search for within possible value labels" + }, + "ids": { + "type": "array", + "description": "List of specific ids to look up", + "items": { + "type": "string" + } + }, + "values": { + "type": "object", + "description": "Map of other field values, used for filter interpolation on possible value source filters" + }, + "useCase": { + "type": "string", + "description": "Use case for possible value search filtering. Controls behavior when filter values are missing.", + "enum": [ + "FORM", + "FILTER" + ] + }, + "labels": { + "type": "array", + "description": "List of specific labels to look up", + "items": { + "type": "string" + } + }, + "processValues": { + "type": "object", + "description": "Map of field values from the current process step, used for filter interpolation" + }, + "filter": { + "description": "Optional default filter to apply to the possible value search", + "$ref": "#/components/schemas/QueryFilter" + }, + "picker": { + "type": "object", + "description": "Record picker request, for a possible value source that declares a picker: options carry the picker's display values and the response says whether more follow (no count)", + "properties": { + "filter": { + "description": "Criteria (only on the picker's filterFields) and orderBys (only on its sort fields or the primary key)", + "$ref": "#/components/schemas/QueryFilter" + }, + "afterId": { + "type": "string", + "description": "Keyset paging: the last option id of the previous page, when ordered by the primary key alone" + }, + "skip": { + "type": "integer", + "description": "Offset paging, for orderings other than the primary key" + }, + "limit": { + "type": "integer", + "description": "Options per page (default: the picker's pageSize; at most 200)" + } + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "tableName", + "description": "Name of the table containing the field.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + }, + { + "name": "fieldName", + "description": "Name of the field whose possible values should be searched.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "partnerPersonId" + } + ], + "responses": { + "200": { + "description": "List of possible value options matching the search criteria.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PossibleValuesResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/processes/{processName}/possibleValues/{fieldName}": { + "post": { + "summary": "Search possible values for a process field", + "description": "Search for possible values associated with an input field on a process.\nReturns a list of id/label pairs that match the given search criteria.", + "operationId": "searchProcessPossibleValues", + "tags": [ + "Processes" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "searchTerm": { + "type": "string", + "description": "Text to search for within possible value labels" + }, + "ids": { + "type": "array", + "description": "List of specific ids to look up", + "items": { + "type": "string" + } + }, + "values": { + "type": "object", + "description": "Map of other field values, used for filter interpolation on possible value source filters" + }, + "useCase": { + "type": "string", + "description": "Use case for possible value search filtering. Controls behavior when filter values are missing.", + "enum": [ + "FORM", + "FILTER" + ] + }, + "labels": { + "type": "array", + "description": "List of specific labels to look up", + "items": { + "type": "string" + } + }, + "processValues": { + "type": "object", + "description": "Map of field values from the current process step, used for filter interpolation" + }, + "filter": { + "description": "Optional default filter to apply to the possible value search", + "$ref": "#/components/schemas/QueryFilter" + }, + "picker": { + "type": "object", + "description": "Record picker request, for a possible value source that declares a picker: options carry the picker's display values and the response says whether more follow (no count)", + "properties": { + "filter": { + "description": "Criteria (only on the picker's filterFields) and orderBys (only on its sort fields or the primary key)", + "$ref": "#/components/schemas/QueryFilter" + }, + "afterId": { + "type": "string", + "description": "Keyset paging: the last option id of the previous page, when ordered by the primary key alone" + }, + "skip": { + "type": "integer", + "description": "Offset paging, for orderings other than the primary key" + }, + "limit": { + "type": "integer", + "description": "Options per page (default: the picker's pageSize; at most 200)" + } + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "processName", + "description": "Name of the process containing the field.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "greetInteractive" + }, + { + "name": "fieldName", + "description": "Name of the field whose possible values should be searched.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "partnerPersonId" + } + ], + "responses": { + "200": { + "description": "List of possible value options matching the search criteria.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PossibleValuesResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/possibleValues/{possibleValueSourceName}": { + "post": { + "summary": "Search a standalone possible value source", + "description": "Search for possible values from a standalone possible value source\n(not associated with a specific table or process field).\nReturns a list of id/label pairs that match the given search criteria.", + "operationId": "searchPossibleValues", + "tags": [ + "General" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "searchTerm": { + "type": "string", + "description": "Text to search for within possible value labels" + }, + "ids": { + "type": "array", + "description": "List of specific ids to look up", + "items": { + "type": "string" + } + }, + "values": { + "type": "object", + "description": "Map of other field values, used for filter interpolation on possible value source filters" + }, + "useCase": { + "type": "string", + "description": "Use case for possible value search filtering. Controls behavior when filter values are missing.", + "enum": [ + "FORM", + "FILTER" + ] + }, + "labels": { + "type": "array", + "description": "List of specific labels to look up", + "items": { + "type": "string" + } + }, + "processValues": { + "type": "object", + "description": "Map of field values from the current process step, used for filter interpolation" + }, + "filter": { + "description": "Optional default filter to apply to the possible value search", + "$ref": "#/components/schemas/QueryFilter" + }, + "picker": { + "type": "object", + "description": "Record picker request, for a possible value source that declares a picker: options carry the picker's display values and the response says whether more follow (no count)", + "properties": { + "filter": { + "description": "Criteria (only on the picker's filterFields) and orderBys (only on its sort fields or the primary key)", + "$ref": "#/components/schemas/QueryFilter" + }, + "afterId": { + "type": "string", + "description": "Keyset paging: the last option id of the previous page, when ordered by the primary key alone" + }, + "skip": { + "type": "integer", + "description": "Offset paging, for orderings other than the primary key" + }, + "limit": { + "type": "integer", + "description": "Options per page (default: the picker's pageSize; at most 200)" + } + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "possibleValueSourceName", + "description": "Name of the possible value source to search.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + } + ], + "responses": { + "200": { + "description": "List of possible value options matching the search criteria.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PossibleValuesResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/widget/{widgetName}": { + "post": { + "summary": "Render a widget", + "description": "Render a widget by name, passing in query parameters as a JSON object in the request body.\nThe response shape varies by widget type.", + "operationId": "getWidgetData", + "tags": [ + "Widgets" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "description": "Dynamic inputs to pass to the widget renderer (e.g. the record id, dropdown selections). The same inputs may instead be sent as query parameters; a body value wins over a query parameter of the same name.", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "parameters": [ + { + "name": "widgetName", + "description": "Name of the widget to render.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "myWidget" + } + ], + "responses": { + "200": { + "description": "The rendered widget data itself (not wrapped): one of the WidgetData shapes, chosen by its `type`.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WidgetData" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/metaData/process/{processName}": { + "get": { + "summary": "Get process metaData", + "description": "Load the full metadata for a single process, including all screens (aka, frontend steps), which a frontend\nneeds to display to users.", + "operationId": "getProcessMetaData", + "tags": [ + "Processes" + ], + "parameters": [ + { + "name": "processName", + "description": "Name of the process to load.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "samplePersonProcess" + } + ], + "responses": { + "200": { + "description": "The full process metadata", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProcessMetaDataResponseV1" + }, + "examples": { + "TODO": { + "value": {} + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/processes/{processName}/init": { + "post": { + "summary": "Initialize a process", + "description": "For a user to start running a process, this endpoint should be called, to start the process\nand run its first step(s) (any backend steps before the first frontend step).\n\nAdditional process-specific values should posted in a form param named `values`, as JSON object\nwith keys defined by the process in question.\n\nFor a process which needs to operate on a set of records that a user selected, see\n`recordsParam`, and `recordIds` or `filterJSON`.\n\nThe response will include a `processUUID`, to be included in all subsequent requests relevant\nto the process.\n\nNote that this request, if it takes longer than a given threshold* to complete, will return a\na `jobUUID`, which should be sent to the `/processes/{processName}/{processUUID}/status/{jobUUID}`\nendpoint, to poll for a status update.\n\n*This threshold has a default value of 3,000 ms., but can be set per-request via the form\nparameter `stepTimeoutMillis`.\n", + "operationId": "initProcess", + "tags": [ + "Processes" + ], + "requestBody": { + "required": false, + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "values": { + "type": "object", + "description": "Process-specific field names and values." + }, + "recordsParam": { + "type": "string", + "description": "Specifies which other query-param will contain the indicator of initial records to pass in to the process.", + "examples": { + "recordIds": { + "value": "recordIds" + }, + "filterJSON": { + "value": "recordIds" + } + } + }, + "recordIds": { + "type": "string", + "description": "Comma-separated list of ids from the table this process is based on, to use as input records for the process. Needs `recordsParam=recordIds` value to be given as well.", + "examples": { + "one id": { + "value": "1701" + }, + "multiple ids": { + "value": "42,47" + } + } + }, + "filterJSON": { + "type": "string", + "description": "JSON encoded QQueryFilter object, to execute against the table this process is based on, to find input records for the process. Needs `recordsParam=filterJSON` value to be given as well.", + "examples": { + "empty filter (all records)": { + "value": "{}" + }, + "filter by a condition": { + "value": "{\"criteria\":[{\"fieldName\":\"id\",\"operator\":\"LESS_THAN\",\"values\":[10]}],\"booleanOperator\":\"AND\"}" + } + } + }, + "stepTimeoutMillis": { + "type": "integer", + "description": "Optionally change the time that the server will wait for the job before letting it go asynchronous. Default value is 3000.", + "examples": { + "shorter timeout": { + "value": "500" + }, + "longer timeout": { + "value": "60000" + } + } + }, + "file": { + "type": "string", + "format": "binary", + "description": "A file upload, for processes which expect to be initialized with an uploaded file." + }, + "tableVariant": { + "type": "string", + "description": "For processes on tables that use variant backends, JSON object naming the variant to use (the same `type` and `id` as in table requests). May also be given as a query parameter.", + "example": "{\"type\":\"store\",\"id\":\"1\"}" + } + } + } + } + } + }, + "parameters": [ + { + "name": "processName", + "description": "Name of the process to initialize", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "samplePersonProcess" + }, + { + "name": "tableVariant", + "description": "For processes on tables that use variant backends, JSON object naming the variant to use (the same `type` and `id` as in table requests).", + "required": false, + "in": "query", + "schema": { + "type": "string" + }, + "example": "{\"type\":\"store\",\"id\":\"1\"}" + } + ], + "responses": { + "200": { + "description": "State of the initialization of the job, with different fields set, based on the\nstatus of the task.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProcessStepResponseV1" + }, + "examples": { + "COMPLETE": { + "value": { + "values": { + "firstLastName": "Aabramson", + "totalAge": 32768 + }, + "processUUID": "01234567-89AB-CDEF-0123-456789ABCDEF", + "nextStep": "reviewScreen", + "type": "COMPLETE" + } + }, + "COMPLETE with metaDataAdjustment": { + "value": { + "values": { + "firstLastName": "Aabramson", + "totalAge": 32768 + }, + "processUUID": "01234567-89AB-CDEF-0123-456789ABCDEF", + "nextStep": "inputScreen", + "processMetaDataAdjustment": { + "updatedFields": { + "someField": { + "isRequired": true, + "isEditable": true, + "name": "someField", + "displayFormat": "%s", + "isHeavy": false, + "type": "STRING", + "validation": { + "required": true + }, + "isHidden": false + } + }, + "updatedFrontendStepList": [ + { + "components": [ + { + "type": "EDIT_FORM" + } + ], + "name": "inputScreen", + "formFields": [ + { + "isRequired": false, + "isEditable": true, + "name": "someField", + "displayFormat": "%s", + "isHeavy": false, + "type": "STRING", + "isHidden": false + } + ] + }, + { + "components": [ + { + "type": "PROCESS_SUMMARY_RESULTS" + } + ], + "name": "resultScreen" + } + ] + }, + "type": "COMPLETE" + } + }, + "JOB_STARTED": { + "value": { + "jobUUID": "98765432-10FE-DCBA-9876-543210FEDCBA", + "processUUID": "01234567-89AB-CDEF-0123-456789ABCDEF", + "type": "JOB_STARTED" + } + }, + "RUNNING": { + "value": { + "current": 47, + "total": 1701, + "processUUID": "01234567-89AB-CDEF-0123-456789ABCDEF", + "type": "RUNNING", + "message": "Processing person records" + } + }, + "ERROR": { + "value": { + "processUUID": "01234567-89AB-CDEF-0123-456789ABCDEF", + "type": "RUNNING" + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/processes/{processName}/{processUUID}/step/{stepName}": { + "post": { + "summary": "Run a step in a process", + "description": "To run the next step in a process, this endpoint should be called, with the `processName`\nand existing `processUUID`, as well as the step that was just completed in the frontend,\ngiven as `stepName`.\n\nAdditional process-specific values should posted in a form param named `values`, as JSON object\nwith keys defined by the process in question.\n\nNote that this request, if it takes longer than a given threshold* to complete, will return a\na `jobUUID`, which should be sent to the `/processes/{processName}/{processUUID}/status/{jobUUID}`\nendpoint, to poll for a status update.\n\n*This threshold has a default value of 3,000 ms., but can be set per-request via the form\nparameter `stepTimeoutMillis`.\n", + "operationId": "stepProcess", + "tags": [ + "Processes" + ], + "requestBody": { + "required": false, + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "values": { + "type": "object", + "description": "Process-specific field names and values." + }, + "stepTimeoutMillis": { + "type": "integer", + "description": "Optionally change the time that the server will wait for the job before letting it go asynchronous. Default value is 3000.", + "examples": { + "shorter timeout": { + "value": "500" + }, + "longer timeout": { + "value": "60000" + } + } + }, + "file": { + "type": "string", + "format": "binary", + "description": "A file upload, for process steps which expect an uploaded file." + }, + "tableVariant": { + "type": "string", + "description": "For processes on tables that use variant backends, JSON object naming the variant to use (the same `type` and `id` as in table requests). May also be given as a query parameter.", + "example": "{\"type\":\"store\",\"id\":\"1\"}" + } + } + } + } + } + }, + "parameters": [ + { + "name": "processName", + "description": "Name of the process to perform the step in.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "samplePersonProcess" + }, + { + "name": "processUUID", + "description": "Unique identifier for this run of the process - as was returned by the `init` call.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "01234567-89AB-CDEF-0123-456789ABCDEF" + }, + { + "name": "stepName", + "description": "Name of the frontend step that the user has just completed.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "inputForm" + }, + { + "name": "tableVariant", + "description": "For processes on tables that use variant backends, JSON object naming the variant to use (the same `type` and `id` as in table requests).", + "required": false, + "in": "query", + "schema": { + "type": "string" + }, + "example": "{\"type\":\"store\",\"id\":\"1\"}" + } + ], + "responses": { + "200": { + "description": "State of the backend's running of the next step(s) of the job, with different fields set,\nbased on the status of the job.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProcessStepResponseV1" + }, + "examples": { + "COMPLETE": { + "value": { + "values": { + "firstLastName": "Aabramson", + "totalAge": 32768 + }, + "processUUID": "01234567-89AB-CDEF-0123-456789ABCDEF", + "nextStep": "reviewScreen", + "type": "COMPLETE" + } + }, + "COMPLETE with metaDataAdjustment": { + "value": { + "values": { + "firstLastName": "Aabramson", + "totalAge": 32768 + }, + "processUUID": "01234567-89AB-CDEF-0123-456789ABCDEF", + "nextStep": "inputScreen", + "processMetaDataAdjustment": { + "updatedFields": { + "someField": { + "isRequired": true, + "isEditable": true, + "name": "someField", + "displayFormat": "%s", + "isHeavy": false, + "type": "STRING", + "validation": { + "required": true + }, + "isHidden": false + } + }, + "updatedFrontendStepList": [ + { + "components": [ + { + "type": "EDIT_FORM" + } + ], + "name": "inputScreen", + "formFields": [ + { + "isRequired": false, + "isEditable": true, + "name": "someField", + "displayFormat": "%s", + "isHeavy": false, + "type": "STRING", + "isHidden": false + } + ] + }, + { + "components": [ + { + "type": "PROCESS_SUMMARY_RESULTS" + } + ], + "name": "resultScreen" + } + ] + }, + "type": "COMPLETE" + } + }, + "JOB_STARTED": { + "value": { + "jobUUID": "98765432-10FE-DCBA-9876-543210FEDCBA", + "processUUID": "01234567-89AB-CDEF-0123-456789ABCDEF", + "type": "JOB_STARTED" + } + }, + "RUNNING": { + "value": { + "current": 47, + "total": 1701, + "processUUID": "01234567-89AB-CDEF-0123-456789ABCDEF", + "type": "RUNNING", + "message": "Processing person records" + } + }, + "ERROR": { + "value": { + "processUUID": "01234567-89AB-CDEF-0123-456789ABCDEF", + "type": "RUNNING" + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/processes/{processName}/{processUUID}/status/{jobUUID}": { + "get": { + "summary": "Get job status", + "description": "Get the status of a running job for a process.\n\nResponse is the same format as for an init or step call that completed synchronously.\n", + "operationId": "getProcessStatus", + "tags": [ + "Processes" + ], + "parameters": [ + { + "name": "processName", + "description": "Name of the process that is being ran", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "samplePersonProcess" + }, + { + "name": "processUUID", + "description": "Unique identifier for this run of the process - as was returned by the `init` call.", + "required": true, + "in": "path", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "01234567-89AB-CDEF-0123-456789ABCDEF" + }, + { + "name": "jobUUID", + "description": "Unique identifier for the asynchronous job being executed, as returned by an `init` or `step` call that went asynch.", + "required": true, + "in": "path", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "98765432-10FE-DCBA-9876-543210FEDCBA" + }, + { + "name": "tableVariant", + "description": "For processes on tables that use variant backends, JSON object naming the variant to use (the same `type` and `id` as in table requests).", + "required": false, + "in": "query", + "schema": { + "type": "string" + }, + "example": "{\"type\":\"store\",\"id\":\"1\"}" + } + ], + "responses": { + "200": { + "description": "State of the backend's running of the specified job, with different fields set,\nbased on the status of the job.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProcessStepResponseV1" + }, + "examples": { + "COMPLETE": { + "value": { + "values": { + "firstLastName": "Aabramson", + "totalAge": 32768 + }, + "processUUID": "01234567-89AB-CDEF-0123-456789ABCDEF", + "nextStep": "reviewScreen", + "type": "COMPLETE" + } + }, + "COMPLETE with metaDataAdjustment": { + "value": { + "values": { + "firstLastName": "Aabramson", + "totalAge": 32768 + }, + "processUUID": "01234567-89AB-CDEF-0123-456789ABCDEF", + "nextStep": "inputScreen", + "processMetaDataAdjustment": { + "updatedFields": { + "someField": { + "isRequired": true, + "isEditable": true, + "name": "someField", + "displayFormat": "%s", + "isHeavy": false, + "type": "STRING", + "validation": { + "required": true + }, + "isHidden": false + } + }, + "updatedFrontendStepList": [ + { + "components": [ + { + "type": "EDIT_FORM" + } + ], + "name": "inputScreen", + "formFields": [ + { + "isRequired": false, + "isEditable": true, + "name": "someField", + "displayFormat": "%s", + "isHeavy": false, + "type": "STRING", + "isHidden": false + } + ] + }, + { + "components": [ + { + "type": "PROCESS_SUMMARY_RESULTS" + } + ], + "name": "resultScreen" + } + ] + }, + "type": "COMPLETE" + } + }, + "JOB_STARTED": { + "value": { + "jobUUID": "98765432-10FE-DCBA-9876-543210FEDCBA", + "processUUID": "01234567-89AB-CDEF-0123-456789ABCDEF", + "type": "JOB_STARTED" + } + }, + "RUNNING": { + "value": { + "current": 47, + "total": 1701, + "processUUID": "01234567-89AB-CDEF-0123-456789ABCDEF", + "type": "RUNNING", + "message": "Processing person records" + } + }, + "ERROR": { + "value": { + "processUUID": "01234567-89AB-CDEF-0123-456789ABCDEF", + "type": "RUNNING" + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/processes/{processName}/{processUUID}/records": { + "get": { + "summary": "Get records from a process", + "description": "Retrieve the records associated with a running or completed process, with support\nfor pagination via skip and limit query parameters.", + "operationId": "getProcessRecords", + "tags": [ + "Processes" + ], + "parameters": [ + { + "name": "processName", + "description": "Name of the process", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "samplePersonProcess" + }, + { + "name": "processUUID", + "description": "Unique identifier for this run of the process", + "required": true, + "in": "path", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "01234567-89AB-CDEF-0123-456789ABCDEF" + }, + { + "name": "skip", + "description": "Number of records to skip (default 0)", + "required": false, + "in": "query", + "schema": { + "type": "integer" + }, + "example": "0" + }, + { + "name": "limit", + "description": "Maximum number of records to return (default 20)", + "required": false, + "in": "query", + "schema": { + "type": "integer" + }, + "example": "20" + }, + { + "name": "tableVariant", + "description": "For processes on tables that use variant backends, JSON object naming the variant to use (the same `type` and `id` as in table requests).", + "required": false, + "in": "query", + "schema": { + "type": "string" + }, + "example": "{\"type\":\"store\",\"id\":\"1\"}" + } + ], + "responses": { + "200": { + "description": "Paginated list of records from the process state.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProcessRecordsResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/processes/{processName}/{processUUID}/cancel": { + "post": { + "summary": "Cancel a running process", + "description": "Cancel a running process. If the process defines a cancel step, it will be executed.", + "operationId": "cancelProcess", + "tags": [ + "Processes" + ], + "parameters": [ + { + "name": "processName", + "description": "Name of the process to cancel", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "samplePersonProcess" + }, + { + "name": "processUUID", + "description": "Unique identifier for this run of the process", + "required": true, + "in": "path", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "01234567-89AB-CDEF-0123-456789ABCDEF" + }, + { + "name": "tableVariant", + "description": "For processes on tables that use variant backends, JSON object naming the variant to use (the same `type` and `id` as in table requests).", + "required": false, + "in": "query", + "schema": { + "type": "string" + }, + "example": "{\"type\":\"store\",\"id\":\"1\"}" + } + ], + "responses": { + "200": { + "description": "Empty JSON object indicating successful cancellation.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProcessCancelResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/processes/{processName}/jobs": { + "post": { + "summary": "Run a process as a durable background job", + "description": "Launch an eligible process as a durable job: it survives pod restarts, runs in checkpointed chunks under leases, and can be paused, resumed, cancelled, restarted and retried with the job control processes on the jobs_job table. Values for the process's frontend steps are given up front. The job runs with the caller's permissions (never more). A launch from the assistant client channel waits for confirmation (status AWAITING_CONFIRMATION). Progress arrives as job.progress and job.status events on the realtime channel record:jobs_job:{jobId}.", + "operationId": "launchProcessJob", + "tags": [ + "Processes" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "description": "The launch request.", + "properties": { + "values": { + "type": "object", + "description": "Process values (what the frontend steps would have collected)." + }, + "filter": { + "type": "object", + "description": "A records filter (QQueryFilter JSON) the process runs over." + }, + "recordIds": { + "type": "array", + "description": "Primary keys the process runs over.", + "items": { + "type": "string" + } + }, + "uploadRefs": { + "type": "array", + "description": "Upload refs from POST /uploads.", + "items": { + "type": "string" + } + }, + "savedBulkLoadProfileId": { + "type": "integer", + "description": "A saved bulk load profile to load with." + }, + "profile": { + "type": "object", + "description": "A bulk load profile (BulkLoadProfile v1 JSON) to load with." + }, + "mode": { + "type": "string", + "description": "EXECUTE (default) or VALIDATE (no store).", + "enum": [ + "EXECUTE", + "VALIDATE" + ] + }, + "priority": { + "type": "integer", + "description": "0-9, default 5 (higher runs first)." + }, + "notifyEmail": { + "type": "boolean", + "description": "Email the owner when the job finishes." + }, + "label": { + "type": "string", + "description": "A label for the job (defaults to the process label)." + }, + "startAfterStep": { + "type": "string", + "description": "The launch point: backend steps after this step run in the job." + }, + "expectedRows": { + "type": "integer", + "description": "A known row count (e.g., from a count)." + } + } + } + } + } + }, + "parameters": [ + { + "name": "processName", + "description": "Name of the process to run as a job", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person.bulkEdit" + } + ], + "responses": { + "200": { + "description": "The new job's id and status.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProcessJobLaunchResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many jobs are waiting for this user (or for the assistant).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/jobs": { + "get": { + "summary": "Jobs: list", + "description": "Requires jobs_job.read and the job owner lock; jobs_admin can see all jobs. Hidden jobs return 404; invalid transitions return 409. Progress polls include a twenty-id overlap for concurrent commits; deduplicate log lines by id. Recent jobs finished in the last seven days.", + "operationId": "listJobs", + "tags": [ + "Processes" + ], + "parameters": [ + { + "name": "scope", + "description": "mine (default), or all (requires jobs_admin)", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "state", + "description": "active (default), recent, or all", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "description": "1-200; default 50", + "required": false, + "in": "query", + "schema": { + "type": "integer" + } + }, + { + "name": "processName", + "description": "Optional process filter", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Job list result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobListResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "Permission denied", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Job not found or not visible", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Invalid job transition", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/jobs/{jobId}": { + "get": { + "summary": "Jobs: detail", + "description": "Requires jobs_job.read and the job owner lock; jobs_admin can see all jobs. Hidden jobs return 404; invalid transitions return 409. Progress polls include a twenty-id overlap for concurrent commits; deduplicate log lines by id. Recent jobs finished in the last seven days.", + "operationId": "getJob", + "tags": [ + "Processes" + ], + "parameters": [ + { + "name": "jobId", + "required": true, + "in": "path", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Job detail result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobDetailV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "Permission denied", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Job not found or not visible", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Invalid job transition", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/jobs/{jobId}/progress": { + "get": { + "summary": "Jobs: progress", + "description": "Requires jobs_job.read and the job owner lock; jobs_admin can see all jobs. Hidden jobs return 404; invalid transitions return 409. Progress polls include a twenty-id overlap for concurrent commits; deduplicate log lines by id. Recent jobs finished in the last seven days.", + "operationId": "getJobProgress", + "tags": [ + "Processes" + ], + "parameters": [ + { + "name": "jobId", + "required": true, + "in": "path", + "schema": { + "type": "integer" + } + }, + { + "name": "afterLogId", + "description": "Last observed log id, default 0; response includes a twenty-id overlap", + "required": false, + "in": "query", + "schema": { + "type": "integer" + } + }, + { + "name": "logLimit", + "description": "1-200 new lines, plus overlap; default 100", + "required": false, + "in": "query", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Job progress result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobProgressPollV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "Permission denied", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Job not found or not visible", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Invalid job transition", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/jobs/{jobId}/cancel": { + "post": { + "summary": "Jobs: cancel", + "description": "Requires jobs_job.read and the job owner lock; jobs_admin can see all jobs. Hidden jobs return 404; invalid transitions return 409. Progress polls include a twenty-id overlap for concurrent commits; deduplicate log lines by id. Recent jobs finished in the last seven days.", + "operationId": "cancelJob", + "tags": [ + "Processes" + ], + "parameters": [ + { + "name": "jobId", + "required": true, + "in": "path", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Job cancel result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobActionResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "Permission denied", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Job not found or not visible", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Invalid job transition", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/jobs/{jobId}/retry": { + "post": { + "summary": "Jobs: retry", + "description": "Requires jobs_job.read and the job owner lock; jobs_admin can see all jobs. Hidden jobs return 404; invalid transitions return 409. Progress polls include a twenty-id overlap for concurrent commits; deduplicate log lines by id. Recent jobs finished in the last seven days.", + "operationId": "retryJob", + "tags": [ + "Processes" + ], + "parameters": [ + { + "name": "jobId", + "required": true, + "in": "path", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Job retry result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobActionResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "Permission denied", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Job not found or not visible", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Invalid job transition", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/jobs/track": { + "post": { + "summary": "Jobs: track", + "description": "Requires jobs_job.read and the job owner lock; jobs_admin can see all jobs. Hidden jobs return 404; invalid transitions return 409. Progress polls include a twenty-id overlap for concurrent commits; deduplicate log lines by id. Recent jobs finished in the last seven days.", + "operationId": "trackJob", + "tags": [ + "Processes" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobTrackRequestV1" + } + } + } + }, + "responses": { + "200": { + "description": "Job track result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JobActionResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "Permission denied", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Job not found or not visible", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Invalid job transition", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/uploads": { + "post": { + "summary": "Upload a file for a job or a bulk load", + "description": "Streams a file into the application's uploads storage and returns an opaque, expiring ref bound to the caller. Pass the ref in uploadRefs when launching a job (POST /processes/{processName}/jobs). Send multipart form data with one file field, or the raw file as the request body with the fileName query parameter.", + "operationId": "upload", + "tags": [ + "Processes" + ], + "requestBody": { + "required": false, + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "description": "One file field.", + "properties": { + "file": { + "type": "string", + "format": "binary", + "description": "The file." + } + } + } + }, + "application/octet-stream": { + "schema": { + "type": "string", + "format": "binary", + "description": "The raw file (give its name in the fileName query parameter)." + } + } + } + }, + "parameters": [ + { + "name": "fileName", + "description": "The file's name, when the body is the raw file (not multipart).", + "required": false, + "in": "query", + "schema": { + "type": "string" + }, + "example": "people.csv" + } + ], + "responses": { + "200": { + "description": "The upload's ref, name, size, content type and expiry.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadRefResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/export": { + "post": { + "summary": "Export records from a table", + "description": "Export records from a table as a downloadable file in the specified format (CSV, XLSX, JSON, TSV).", + "operationId": "exportTable", + "tags": [ + "Tables" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "format": { + "type": "string", + "description": "Export format: csv, xlsx, json, tsv" + }, + "filename": { + "type": "string", + "description": "Optional filename for the download. Generated if absent." + }, + "filter": { + "description": "QueryFilter to specify matching records to export", + "$ref": "#/components/schemas/QueryFilter" + }, + "fieldNames": { + "type": "array", + "description": "Optional subset of field names to include in the export", + "items": { + "type": "string" + } + }, + "limit": { + "type": "integer", + "description": "Optional maximum number of records to export" + }, + "includeHeaderRow": { + "type": "boolean", + "description": "Whether to include a header row (default true)" + }, + "tableVariant": { + "description": "For tables that use variant backends, the variant to export from (the same `type` and `id` as in query requests).", + "$ref": "#/components/schemas/TableVariant" + } + } + } + } + } + }, + "parameters": [ + { + "name": "tableName", + "description": "Name of the table to export.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + } + ], + "responses": { + "200": { + "description": "Binary file content in the requested export format", + "content": { + "application/octet-stream": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/table/{tableName}/{primaryKey}/{fieldName}/{filename}": { + "get": { + "summary": "Download a field value from a record", + "description": "Download the binary content of a blob field from a specific record.", + "operationId": "downloadRecordFieldFile", + "tags": [ + "Tables" + ], + "parameters": [ + { + "name": "tableName", + "description": "Name of the table containing the record.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + }, + { + "name": "primaryKey", + "description": "Primary key value of the record.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "42" + }, + { + "name": "fieldName", + "description": "Name of the field to download.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "photo" + }, + { + "name": "filename", + "description": "Filename for the downloaded content.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "photo.jpg" + } + ], + "responses": { + "200": { + "description": "Binary file content", + "content": { + "application/octet-stream": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/download/{file}": { + "get": { + "summary": "Download a file", + "description": "Download a file from server-side storage by file path or storage table reference.", + "operationId": "download", + "tags": [ + "General" + ], + "parameters": [ + { + "name": "file", + "description": "Filename for the download.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "report.csv" + }, + { + "name": "filePath", + "description": "Server-side file path to download from.", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "storageTableName", + "description": "Name of the storage table to download from.", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "storageReference", + "description": "Storage reference key for the file.", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Binary file content", + "content": { + "application/octet-stream": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/reports/{reportName}": { + "get": { + "summary": "Run a report and download the file", + "description": "Run a report and stream the generated file in the requested format. The report's input fields are given as\nquery parameters named for the fields; a missing required input is a 400. Requires permission to run the report.", + "operationId": "runReport", + "tags": [ + "Reports" + ], + "parameters": [ + { + "name": "reportName", + "description": "Name of the report to run.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "personReport" + }, + { + "name": "format", + "description": "Output format: csv, xlsx, json (as for table export).", + "required": true, + "in": "query", + "schema": { + "type": "string" + }, + "example": "csv" + } + ], + "responses": { + "200": { + "description": "The generated report file, in the requested format", + "content": { + "application/octet-stream": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/bulkLoad/uploads/{uploadRef}/profile": { + "get": { + "summary": "Profile an uploaded file for a bulk load", + "description": "Read an uploaded file (by its upload ref, which must be the session user's) and describe it for a bulk load into a table: whether row 1 is a header row, and each column's inferred type, percent blank, distinct count, maximum length and pattern class. Sample values are included only for columns mapped to an unclassified (or PUBLIC) field, or for every column when the request's `X-QQQ-AI-Route` header is `hipaa`; unmapped columns never get samples otherwise. Requires the table's bulk-insert process permission. Nothing is stored.", + "operationId": "getBulkLoadUploadProfile", + "tags": [ + "Bulk Load" + ], + "parameters": [ + { + "name": "uploadRef", + "description": "The opaque ref of an upload the session user owns.", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "tableName", + "description": "The table the file would be loaded into.", + "required": true, + "in": "query", + "schema": { + "type": "string" + }, + "example": "person" + }, + { + "name": "sampleCount", + "description": "Sample values per column, where allowed (0 to 20; default 5).", + "required": false, + "in": "query", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "The upload's header guess and column profiles", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkLoadUploadProfileResponseV1" + }, + "examples": { + "profile": { + "value": { + "uploadRef": "u_4f2c", + "fileName": "people.csv", + "hasHeaderRow": true, + "rowsProfiled": 250 + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/bulkLoad/{tableName}/suggestMapping": { + "post": { + "summary": "Suggest a bulk load mapping for an uploaded file", + "description": "Run the bulk load mapping suggester over an uploaded file's header row and return a v1 bulk load profile, the file columns it leaves unmapped, the required fields it does not fill, and the mapped fields with a possible value source (whose file values may need value mapping). The upload must be the session user's. Requires the table's bulk-insert process permission. Nothing is stored.", + "operationId": "suggestBulkLoadMapping", + "tags": [ + "Bulk Load" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "uploadRef": { + "type": "string", + "description": "The opaque ref of an upload the session user owns." + }, + "isBulkEdit": { + "type": "boolean", + "description": "Suggest a bulk edit profile (default false: bulk insert)." + } + } + } + } + } + }, + "parameters": [ + { + "name": "tableName", + "description": "The table the file would be loaded into.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + } + ], + "responses": { + "200": { + "description": "The suggested profile and what it leaves unmapped", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkLoadSuggestMappingResponseV1" + }, + "examples": { + "suggestion": { + "value": { + "profile": { + "version": "v1", + "layout": "FLAT", + "hasHeaderRow": true + } + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/bulkLoad/{tableName}/validate": { + "post": { + "summary": "Dry-run a bulk load profile over an uploaded file", + "description": "Run the table's bulk-insert process over an uploaded file with the given v1 bulk load profile - the same mapping, value mapping and validation a real load uses - and stop at its review step, so nothing is stored. SAMPLE validates the first 100 rows; FULL the whole file. Returns the standard process summary lines, counts, and error groups with row numbers. Values of classified fields are left out unless the request's `X-QQQ-AI-Route` header is `hipaa`. The upload must be the session user's. Requires the table's bulk-insert process permission.", + "operationId": "validateBulkLoad", + "tags": [ + "Bulk Load" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "uploadRef": { + "type": "string", + "description": "The opaque ref of an upload the session user owns." + }, + "profile": { + "type": "object", + "description": "A v1 bulk load profile: version, layout (FLAT), hasHeaderRow, and fieldList entries of fieldName, columnIndex, headerName, defaultValue, doValueMapping, valueMappings and clearIfEmpty." + }, + "mode": { + "type": "string", + "description": "SAMPLE (default, the first 100 rows) or FULL.", + "enum": [ + "SAMPLE", + "FULL" + ] + } + } + } + } + } + }, + "parameters": [ + { + "name": "tableName", + "description": "The table the file would be loaded into.", + "required": true, + "in": "path", + "schema": { + "type": "string" + }, + "example": "person" + } + ], + "responses": { + "200": { + "description": "The dry run's summary and error groups", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkLoadValidateResponseV1" + }, + "examples": { + "dryRun": { + "value": { + "mode": "SAMPLE", + "processName": "person.bulkInsert", + "recordCount": 3, + "okCount": 2, + "errorCount": 1 + } + } + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/esb/overview": { + "get": { + "summary": "ESB overview", + "description": "Every broker connection and destination, with the tables and processes publishing to each and the triggers consuming it, and what the user may do. Needs the ESB app permission.", + "operationId": "getEsbOverview", + "tags": [ + "ESB" + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EsbOverviewResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/esb/table/{table}": { + "get": { + "summary": "ESB of a table", + "description": "The destinations a table publishes its events to, the triggers subscribed to them (on processes the user can access), and what the user may do. Needs READ on the table.", + "operationId": "getEsbTableByTable", + "tags": [ + "ESB" + ], + "parameters": [ + { + "name": "table", + "description": "Table name.", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EsbTableResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/esb/process/{process}": { + "get": { + "summary": "ESB of a process", + "description": "The destinations a process publishes its lifecycle events to, the triggers that run it, and what the user may do. Needs access to the process.", + "operationId": "getEsbProcessByProcess", + "tags": [ + "ESB" + ], + "parameters": [ + { + "name": "process", + "description": "Process name.", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EsbProcessResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/esb/deadLetters/{trigger}": { + "get": { + "summary": "Dead letters of a trigger", + "description": "A page of the messages on a trigger dead-letter destination, oldest first. Needs the operate permission.", + "operationId": "getEsbDeadLettersByTrigger", + "tags": [ + "ESB" + ], + "parameters": [ + { + "name": "trigger", + "description": "Trigger name.", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "description": "Messages to skip (default 0).", + "required": false, + "in": "query", + "schema": { + "type": "integer" + } + }, + { + "name": "limit", + "description": "Messages to return (default and maximum set by the server).", + "required": false, + "in": "query", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EsbMessagePageResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/esb/messages/{destination}": { + "get": { + "summary": "Messages on a destination", + "description": "A page of the messages waiting on a destination (or, with trigger, on that trigger subscription of a topic), oldest first. Needs the operate permission.", + "operationId": "getEsbMessagesByDestination", + "tags": [ + "ESB" + ], + "parameters": [ + { + "name": "destination", + "description": "Destination name.", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "trigger", + "description": "For a topic: the trigger whose subscription to browse.", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "offset", + "description": "Messages to skip (default 0).", + "required": false, + "in": "query", + "schema": { + "type": "integer" + } + }, + { + "name": "limit", + "description": "Messages to return (default and maximum set by the server).", + "required": false, + "in": "query", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EsbMessagePageResponseV1" + } + } + } + }, + "400": { + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "401": { + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "403": { + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "404": { + "description": "Not found, or not visible to this user (code NOT_FOUND).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "409": { + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + }, + "429": { + "description": "Too many requests (code RATE_LIMITED); retry later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + } + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ] + } + }, + "/qqq/v1/health/summary": { + "get": { + "description": "Requires health.read permission. Returns redacted health state.", + "operationId": "getHealthSummary", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HealthSummaryV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Health summary", + "tags": [ + "Health" + ] + } + }, + "/qqq/v1/health/components/{name}": { + "get": { + "description": "Requires health.read permission. Returns redacted health state.", + "operationId": "getHealthComponentsByName", + "parameters": [ + { + "description": "Stable health check or component name.", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HealthComponentV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Health component", + "tags": [ + "Health" + ] + } + }, + "/qqq/v1/health/checks/{name}/history": { + "get": { + "description": "Requires health.read permission. Returns redacted health state.", + "operationId": "getHealthChecksByNameHistory", + "parameters": [ + { + "description": "Stable health check or component name.", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "limit is capped at 500; from/to are inclusive ISO-8601 instants.", + "in": "query", + "name": "from", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "limit is capped at 500; from/to are inclusive ISO-8601 instants.", + "in": "query", + "name": "to", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "limit is capped at 500; from/to are inclusive ISO-8601 instants.", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HealthHistoryV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Health history", + "tags": [ + "Health" + ] + } + }, + "/qqq/v1/health/checks/{name}/run": { + "post": { + "description": "Requires health.write permission. Returns redacted health state.", + "operationId": "postHealthChecksByNameRun", + "parameters": [ + { + "description": "Stable health check or component name.", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HealthRunV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Health run", + "tags": [ + "Health" + ] + } + }, + "/qqq/v1/alerts/inbox/summary": { + "get": { + "description": "Uses the signed-in caller's permissions and record visibility.", + "operationId": "alertsInboxSummary", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AlertsInboxSummaryV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Read the bell summary", + "tags": [ + "alerts" + ] + } + }, + "/qqq/v1/alerts/inbox": { + "get": { + "description": "Uses the signed-in caller's permissions and record visibility.", + "operationId": "alertsInbox", + "parameters": [ + { + "description": "all or unread; other values behave as all.", + "in": "query", + "name": "status", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Case-insensitive category filter.", + "in": "query", + "name": "category", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Case-insensitive severity filter.", + "in": "query", + "name": "severity", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Default 0; negatives clamp to 0; malformed values use the default.", + "in": "query", + "name": "offset", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Default 25; clamped to 1..100; malformed values use the default.", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AlertsInboxPageV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Page the notification inbox", + "tags": [ + "alerts" + ] + } + }, + "/qqq/v1/alerts/inbox/read": { + "post": { + "description": "Uses the signed-in caller's permissions and record visibility.", + "operationId": "alertsInboxRead", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AlertsInboxTargetV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AlertsMutationResultV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Mark own notifications read", + "tags": [ + "alerts" + ] + } + }, + "/qqq/v1/alerts/inbox/unread": { + "post": { + "description": "Uses the signed-in caller's permissions and record visibility.", + "operationId": "alertsInboxUnread", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AlertsUnreadTargetV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AlertsMutationResultV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Mark own notifications unread", + "tags": [ + "alerts" + ] + } + }, + "/qqq/v1/alerts/inbox/dismiss": { + "post": { + "description": "Uses the signed-in caller's permissions and record visibility.", + "operationId": "alertsInboxDismiss", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AlertsInboxTargetV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AlertsMutationResultV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Dismiss own notifications", + "tags": [ + "alerts" + ] + } + }, + "/qqq/v1/alerts/record-panel": { + "get": { + "description": "Uses the signed-in caller's permissions and record visibility.", + "operationId": "alertsRecordPanel", + "parameters": [ + { + "description": "Parent table name.", + "in": "query", + "name": "tableName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record key.", + "in": "query", + "name": "recordId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AlertsRecordPanelV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Read visible alerts for a record", + "tags": [ + "alerts" + ] + } + }, + "/qqq/v1/assistant/config": { + "get": { + "description": "Whether the assistant is available to this user, its persona and limits", + "operationId": "getAssistantConfig", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AssistantConfigResponseV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "No access to the assistant" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (or not the user's own)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Already finished or decided" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Budget or rate limit" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Disabled, not configured, or the kill switch is on" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Whether the assistant is available to this user, its persona and limits", + "tags": [ + "assistant" + ] + } + }, + "/qqq/v1/assistant/conversations": { + "get": { + "description": "The user's own conversations", + "operationId": "getAssistantConversations", + "parameters": [ + { + "description": "ARCHIVED for archived conversations; active ones by default.", + "in": "query", + "name": "status", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AssistantConversationListResponseV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "No access to the assistant" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (or not the user's own)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Already finished or decided" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Budget or rate limit" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Disabled, not configured, or the kill switch is on" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "The user's own conversations", + "tags": [ + "assistant" + ] + }, + "post": { + "description": "Start a conversation", + "operationId": "postAssistantConversations", + "requestBody": { + "content": { + "application/json": { + "schema": { + "description": "Optional title and the page context it starts from.", + "properties": { + "title": { + "type": "string" + }, + "context": { + "additionalProperties": true, + "description": "route, tableName, recordId, filter, selectedIds.", + "type": "object" + } + }, + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AssistantConversationV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "No access to the assistant" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (or not the user's own)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Already finished or decided" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Budget or rate limit" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Disabled, not configured, or the kill switch is on" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Start a conversation", + "tags": [ + "assistant" + ] + } + }, + "/qqq/v1/assistant/conversations/{id}": { + "delete": { + "description": "Delete a conversation", + "operationId": "deleteAssistantConversationsById", + "parameters": [ + { + "description": "The conversation id.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "Done (no body)" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "No access to the assistant" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (or not the user's own)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Already finished or decided" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Budget or rate limit" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Disabled, not configured, or the kill switch is on" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Delete a conversation", + "tags": [ + "assistant" + ] + }, + "get": { + "description": "A conversation and a page of its messages", + "operationId": "getAssistantConversationsById", + "parameters": [ + { + "description": "The conversation id.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "description": "Only messages older than this message id.", + "in": "query", + "name": "before", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Page size (default 50, at most 200).", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AssistantConversationDetailResponseV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "No access to the assistant" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (or not the user's own)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Already finished or decided" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Budget or rate limit" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Disabled, not configured, or the kill switch is on" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "A conversation and a page of its messages", + "tags": [ + "assistant" + ] + }, + "patch": { + "description": "Rename, pin, archive or mark read a conversation", + "operationId": "patchAssistantConversationsById", + "parameters": [ + { + "description": "The conversation id.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "description": "The changed properties.", + "properties": { + "title": { + "type": "string" + }, + "pinned": { + "type": "boolean" + }, + "status": { + "description": "ACTIVE or ARCHIVED.", + "type": "string" + }, + "read": { + "description": "Since 1.6.0: true sets unreadCount to 0 (the user watched the reply stream in). Only true is accepted.", + "type": "boolean" + } + }, + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AssistantConversationV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "No access to the assistant" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (or not the user's own)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Already finished or decided" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Budget or rate limit" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Disabled, not configured, or the kill switch is on" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Rename, pin, archive or mark read a conversation", + "tags": [ + "assistant" + ] + } + }, + "/qqq/v1/assistant/conversations/{id}/turns": { + "post": { + "description": "Ask: start a turn and stream the reply as server-sent events", + "operationId": "postAssistantConversationsByIdTurns", + "parameters": [ + { + "description": "The conversation id.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "description": "The user's text and the page context hint.", + "properties": { + "text": { + "description": "The user's message.", + "type": "string" + }, + "pageContext": { + "additionalProperties": true, + "description": "Where the user is in the app: route, tableName, recordId, filter, selectedIds, and attachments (at most 5 of {uploadRef, fileName}, the user's own uploads; their content is read for this question, as untrusted data).", + "type": "object" + }, + "concurrency": { + "description": "supersede or concurrent (case-insensitive); defaults to the host configuration.", + "type": "string" + } + }, + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "text/event-stream": { + "schema": { + "$ref": "#/components/schemas/AssistantTurnEventV1" + } + } + }, + "description": "The turn's events, until message.end" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "No access to the assistant" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (or not the user's own)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Already finished or decided" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Budget or rate limit" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Disabled, not configured, or the kill switch is on" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Ask: start a turn and stream the reply as server-sent events", + "tags": [ + "assistant" + ] + } + }, + "/qqq/v1/assistant/turns/{turnId}/events": { + "get": { + "description": "Resume a turn's events after a sequence number (replay, then the live tail)", + "operationId": "getAssistantTurnsByTurnIdEvents", + "parameters": [ + { + "description": "The turn id.", + "in": "path", + "name": "turnId", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "description": "The last sequence number already received (0 for all).", + "in": "query", + "name": "after", + "required": false, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "text/event-stream": { + "schema": { + "$ref": "#/components/schemas/AssistantTurnEventV1" + } + } + }, + "description": "The turn's events after `after`, until message.end" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "No access to the assistant" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (or not the user's own)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Already finished or decided" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Budget or rate limit" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Disabled, not configured, or the kill switch is on" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Resume a turn's events after a sequence number (replay, then the live tail)", + "tags": [ + "assistant" + ] + } + }, + "/qqq/v1/assistant/turns/{turnId}/cancel": { + "post": { + "description": "Stop a running turn", + "operationId": "postAssistantTurnsByTurnIdCancel", + "parameters": [ + { + "description": "The turn id.", + "in": "path", + "name": "turnId", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AssistantStatusResponseV1" + } + } + }, + "description": "Successful Response" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AssistantStatusResponseV1" + } + } + }, + "description": "Legacy replica: cancellation accepted" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "No access to the assistant" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (or not the user's own)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Already finished or decided" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Budget or rate limit" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Disabled, not configured, or the kill switch is on" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Stop a running turn", + "tags": [ + "assistant" + ] + } + }, + "/qqq/v1/assistant/turns/active": { + "get": { + "description": "Find the user's active assistant runs", + "operationId": "getAssistantTurnsActive", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AssistantActiveTurnsResponseV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "No access to the assistant" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (or not the user's own)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Already finished or decided" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Budget or rate limit" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Disabled, not configured, or the kill switch is on" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Find the user's active assistant runs", + "tags": [ + "assistant" + ] + } + }, + "/qqq/v1/assistant/messages/{id}/feedback": { + "post": { + "description": "Thumbs up or down on an assistant message", + "operationId": "postAssistantMessagesByIdFeedback", + "parameters": [ + { + "description": "The assistant message id.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "description": "The rating and an optional reason or comment.", + "properties": { + "rating": { + "description": "1 or -1.", + "type": "integer" + }, + "reason": { + "type": "string" + }, + "comment": { + "type": "string" + } + }, + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "Done (no body)" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "No access to the assistant" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (or not the user's own)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Already finished or decided" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Budget or rate limit" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Disabled, not configured, or the kill switch is on" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Thumbs up or down on an assistant message", + "tags": [ + "assistant" + ] + } + }, + "/qqq/v1/assistant/actions/{id}": { + "get": { + "description": "A write the assistant proposed, and its state", + "operationId": "getAssistantActionsById", + "parameters": [ + { + "description": "The pending action id.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AssistantActionV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "No access to the assistant" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (or not the user's own)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Already finished or decided" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Budget or rate limit" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Disabled, not configured, or the kill switch is on" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "A write the assistant proposed, and its state", + "tags": [ + "assistant" + ] + } + }, + "/qqq/v1/assistant/actions/{id}/confirm": { + "post": { + "description": "Confirm a proposed write: it runs once, through the UI API, with this request's session", + "operationId": "postAssistantActionsByIdConfirm", + "parameters": [ + { + "description": "The pending action id.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AssistantActionV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "No access to the assistant" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (or not the user's own)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Already finished or decided" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Budget or rate limit" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Disabled, not configured, or the kill switch is on" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Confirm a proposed write: it runs once, through the UI API, with this request's session", + "tags": [ + "assistant" + ] + } + }, + "/qqq/v1/assistant/actions/{id}/reject": { + "post": { + "description": "Cancel a proposed write; nothing changes", + "operationId": "postAssistantActionsByIdReject", + "parameters": [ + { + "description": "The pending action id.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AssistantActionV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "No access to the assistant" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (or not the user's own)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Already finished or decided" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Budget or rate limit" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Disabled, not configured, or the kill switch is on" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Cancel a proposed write; nothing changes", + "tags": [ + "assistant" + ] + } + }, + "/qqq/v1/assistant/access": { + "get": { + "description": "Explain access: which UI API operations the assistant could call for this user, and why not", + "operationId": "getAssistantAccess", + "parameters": [ + { + "description": "Only this table.", + "in": "query", + "name": "table", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Only the tables this text mentions.", + "in": "query", + "name": "prompt", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Attribute this request to an owned turn.", + "in": "query", + "name": "turnId", + "required": false, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AssistantAccessResponseV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "No access to the assistant" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (or not the user's own)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Already finished or decided" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Budget or rate limit" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Disabled, not configured, or the kill switch is on" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Explain access: which UI API operations the assistant could call for this user, and why not", + "tags": [ + "assistant" + ] + } + }, + "/qqq/v1/assistant/client-errors": { + "post": { + "description": "Report an error the client hit while showing the assistant (stored for administrators, rate limited per user)", + "operationId": "postAssistantClientErrors", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AssistantClientErrorReportV1" + } + } + }, + "required": true + }, + "responses": { + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AssistantClientErrorResponseV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "No access to the assistant" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (or not the user's own)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Already finished or decided" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Budget or rate limit" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Disabled, not configured, or the kill switch is on" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Report an error the client hit while showing the assistant (stored for administrators, rate limited per user)", + "tags": [ + "assistant" + ] + } + }, + "/qqq/v1/qbit/collaboration/presence": { + "delete": { + "description": "Leave presence. Uses the signed-in caller's permissions and record visibility.", + "operationId": "deleteQbitCollaborationPresence", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationPresenceLeaveV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationMutationResultV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Leave presence", + "tags": [ + "collaboration" + ] + }, + "get": { + "description": "Get presence snapshot. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationPresence", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "query", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "query", + "name": "pk", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationPresenceSnapshotV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Get presence snapshot", + "tags": [ + "collaboration" + ] + }, + "post": { + "description": "Renew presence. Uses the signed-in caller's permissions and record visibility.", + "operationId": "postQbitCollaborationPresence", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationPresenceRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationPresenceSnapshotV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Renew presence", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/favorites": { + "delete": { + "description": "Unstar a target. Uses the signed-in caller's permissions and record visibility.", + "operationId": "deleteQbitCollaborationFavorites", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationTargetRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationMutationResultV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Unstar a target", + "tags": [ + "collaboration" + ] + }, + "get": { + "description": "List personal favorites. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationFavorites", + "parameters": [ + { + "description": "Maximum items to return, from 1 to 100; default 20.", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque nextCursor returned by the previous page; omit for the first page.", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationFavoriteListV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "List personal favorites", + "tags": [ + "collaboration" + ] + }, + "put": { + "description": "Star a target. Uses the signed-in caller's permissions and record visibility.", + "operationId": "putQbitCollaborationFavorites", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationTargetRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationMutationResultV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Star a target", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/recents": { + "get": { + "description": "List recent targets. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationRecents", + "parameters": [ + { + "description": "Maximum items to return, from 1 to 100; default 20.", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque nextCursor returned by the previous page; omit for the first page.", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationRecentListV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "List recent targets", + "tags": [ + "collaboration" + ] + }, + "post": { + "description": "Record a recent view. Uses the signed-in caller's permissions and record visibility.", + "operationId": "postQbitCollaborationRecents", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationTargetRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationMutationResultV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Record a recent view", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/favorites/order": { + "patch": { + "description": "Reorder personal favorites. Uses the signed-in caller's permissions and record visibility.", + "operationId": "patchQbitCollaborationFavoritesOrder", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationFavoriteOrderRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationMutationResultV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Reorder personal favorites", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/attachments": { + "get": { + "description": "List record attachments. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationRecordsByTableByPkAttachments", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Maximum items to return, from 1 to 100; default 20.", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque nextCursor returned by the previous page; omit for the first page.", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationAttachmentListV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "List record attachments", + "tags": [ + "collaboration" + ] + }, + "post": { + "description": "Upload an attachment. Uses the signed-in caller's permissions and record visibility.", + "operationId": "postQbitCollaborationRecordsByTableByPkAttachments", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/CollaborationAttachmentUploadRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationAttachmentV1" + } + } + }, + "description": "Uploaded attachment" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Upload an attachment", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/attachments/{id}/download": { + "get": { + "description": "Get a temporary download URL; clients follow url. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationAttachmentsByIdDownload", + "parameters": [ + { + "description": "Collaboration object identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationDownloadV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Get a temporary download URL; clients follow url", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/attachments/{id}/preview": { + "get": { + "description": "Get a temporary preview URL; clients follow url. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationAttachmentsByIdPreview", + "parameters": [ + { + "description": "Collaboration object identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationDownloadV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Get a temporary preview URL; clients follow url", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/attachments/{id}": { + "delete": { + "description": "Delete an attachment. Uses the signed-in caller's permissions and record visibility.", + "operationId": "deleteQbitCollaborationAttachmentsById", + "parameters": [ + { + "description": "Collaboration object identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationMutationResultV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Delete an attachment", + "tags": [ + "collaboration" + ] + }, + "patch": { + "description": "Rename or describe an attachment. Uses the signed-in caller's permissions and record visibility.", + "operationId": "patchQbitCollaborationAttachmentsById", + "parameters": [ + { + "description": "Collaboration object identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationAttachmentPatchRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationAttachmentV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Rename or describe an attachment", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/tags": { + "get": { + "description": "Search table tag vocabulary. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationTags", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "query", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Text to search in display names or vocabulary.", + "in": "query", + "name": "q", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Maximum items to return, from 1 to 100; default 20.", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationTagListV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Search table tag vocabulary", + "tags": [ + "collaboration" + ] + }, + "post": { + "description": "Create or suggest a tag. Uses the signed-in caller's permissions and record visibility.", + "operationId": "postQbitCollaborationTags", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationTagCreateRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationTagV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Create or suggest a tag", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/tags": { + "get": { + "description": "List applied record tags. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationRecordsByTableByPkTags", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Maximum items to return, from 1 to 100; default 20.", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque nextCursor returned by the previous page; omit for the first page.", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationTagListV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "List applied record tags", + "tags": [ + "collaboration" + ] + }, + "put": { + "description": "Add and remove record tags. Uses the signed-in caller's permissions and record visibility.", + "operationId": "putQbitCollaborationRecordsByTableByPkTags", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationTagApplyRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationTagListV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Add and remove record tags", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/comments": { + "get": { + "description": "Page record comment threads. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationRecordsByTableByPkComments", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Maximum items to return, from 1 to 100; default 20.", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque nextCursor returned by the previous page; omit for the first page.", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationCommentPageV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Page record comment threads", + "tags": [ + "collaboration" + ] + }, + "post": { + "description": "Post a comment or reply. Uses the signed-in caller's permissions and record visibility.", + "operationId": "postQbitCollaborationRecordsByTableByPkComments", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationCommentPostRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationCommentV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Post a comment or reply", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/comments/{id}": { + "delete": { + "description": "Delete a comment thread. Uses the signed-in caller's permissions and record visibility.", + "operationId": "deleteQbitCollaborationCommentsById", + "parameters": [ + { + "description": "Collaboration object identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationMutationResultV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Delete a comment thread", + "tags": [ + "collaboration" + ] + }, + "patch": { + "description": "Edit the caller's comment. Uses the signed-in caller's permissions and record visibility.", + "operationId": "patchQbitCollaborationCommentsById", + "parameters": [ + { + "description": "Collaboration object identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationCommentEditRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationCommentV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Edit the caller's comment", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/comments/{id}/resolve": { + "post": { + "description": "Resolve a comment thread. Uses the signed-in caller's permissions and record visibility.", + "operationId": "postQbitCollaborationCommentsByIdResolve", + "parameters": [ + { + "description": "Collaboration object identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationMutationResultV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Resolve a comment thread", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/comments/{id}/reopen": { + "post": { + "description": "Reopen a comment thread. Uses the signed-in caller's permissions and record visibility.", + "operationId": "postQbitCollaborationCommentsByIdReopen", + "parameters": [ + { + "description": "Collaboration object identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationMutationResultV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Reopen a comment thread", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/comments/{id}/history": { + "get": { + "description": "Read comment edit history. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationCommentsByIdHistory", + "parameters": [ + { + "description": "Collaboration object identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Maximum items to return, from 1 to 100; default 20.", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque nextCursor returned by the previous page; omit for the first page.", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationCommentHistoryV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Read comment edit history", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/mentions/candidates": { + "get": { + "description": "Find people to mention on a record. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationMentionsCandidates", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "query", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "query", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Text to search in display names or vocabulary.", + "in": "query", + "name": "q", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Maximum items to return, from 1 to 100; default 20.", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque nextCursor returned by the previous page; omit for the first page.", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationMentionCandidateListV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Find people to mention on a record", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/follow": { + "delete": { + "description": "Unfollow a record. Uses the signed-in caller's permissions and record visibility.", + "operationId": "deleteQbitCollaborationRecordsByTableByPkFollow", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationFollowStateV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Unfollow a record", + "tags": [ + "collaboration" + ] + }, + "get": { + "description": "Get the caller's follow state. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationRecordsByTableByPkFollow", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationFollowStateV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Get the caller's follow state", + "tags": [ + "collaboration" + ] + }, + "put": { + "description": "Follow a record and configure notifications. Uses the signed-in caller's permissions and record visibility.", + "operationId": "putQbitCollaborationRecordsByTableByPkFollow", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationFollowRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationFollowStateV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Follow a record and configure notifications", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/followers": { + "get": { + "description": "List record followers. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationRecordsByTableByPkFollowers", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Maximum items to return, from 1 to 100; default 20.", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque nextCursor returned by the previous page; omit for the first page.", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationFollowerListV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "List record followers", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/timeline": { + "get": { + "description": "Page the merged record timeline. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationRecordsByTableByPkTimeline", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Timeline continuation token; alias for cursor. Supply only one.", + "in": "query", + "name": "before", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Comma-separated AUDIT, ACTIVITY or activity type names (for example COMMENTED).", + "in": "query", + "name": "types", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Maximum items to return, from 1 to 100; default 20.", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque nextCursor returned by the previous page; omit for the first page.", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationTimelinePageV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Page the merged record timeline", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/people": { + "get": { + "description": "Search the active people directory. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationPeople", + "parameters": [ + { + "description": "Text to search in display names or vocabulary.", + "in": "query", + "name": "q", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Maximum items to return, from 1 to 100; default 20.", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationPersonListV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Search the active people directory", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/people/{userId}": { + "get": { + "description": "Get an active directory person. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationPeopleByUserId", + "parameters": [ + { + "description": "Stable directory user identity.", + "in": "path", + "name": "userId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationPersonV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Get an active directory person", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/link": { + "get": { + "description": "Get a record link. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationRecordsByTableByPkLink", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationLinkV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Get a record link", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/shares/preview": { + "post": { + "description": "Preview share recipients. Uses the signed-in caller's permissions and record visibility.", + "operationId": "postQbitCollaborationRecordsByTableByPkSharesPreview", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationShareRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationSharePreviewV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Preview share recipients", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/shares": { + "post": { + "description": "Share a record. Uses the signed-in caller's permissions and record visibility.", + "operationId": "postQbitCollaborationRecordsByTableByPkShares", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationShareRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationShareListV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Share a record", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/access-requests": { + "post": { + "description": "Request access to a record. Uses the signed-in caller's permissions and record visibility.", + "operationId": "postQbitCollaborationAccessRequests", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationAccessRequestCreateRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationAccessRequestV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Request access to a record", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/access-requests/mine": { + "get": { + "description": "List my access requests. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationAccessRequestsMine", + "parameters": [ + { + "description": "Maximum items to return, from 1 to 100; default 20.", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque nextCursor returned by the previous page; omit for the first page.", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationAccessRequestListV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "List my access requests", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/tasks": { + "get": { + "description": "List record tasks. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationRecordsByTableByPkTasks", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Include completed and cancelled tasks; default false.", + "in": "query", + "name": "includeDone", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Maximum items to return, from 1 to 100; default 20.", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque nextCursor returned by the previous page; omit for the first page.", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationTaskListV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "List record tasks", + "tags": [ + "collaboration" + ] + }, + "post": { + "description": "Create a task. Uses the signed-in caller's permissions and record visibility.", + "operationId": "postQbitCollaborationRecordsByTableByPkTasks", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationTaskCreateRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationTaskV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Create a task", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/tasks/{id}": { + "patch": { + "description": "Update a task. Uses the signed-in caller's permissions and record visibility.", + "operationId": "patchQbitCollaborationTasksById", + "parameters": [ + { + "description": "Collaboration object identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationTaskPatchRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationTaskV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Update a task", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/tasks/mine": { + "get": { + "description": "List my tasks. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationTasksMine", + "parameters": [ + { + "description": "Task status: OPEN (default), DONE or CANCELLED.", + "in": "query", + "name": "status", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Maximum items to return, from 1 to 100; default 20.", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque nextCursor returned by the previous page; omit for the first page.", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationTaskListV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "List my tasks", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/assignment": { + "put": { + "description": "Set record owner and assignee. Uses the signed-in caller's permissions and record visibility.", + "operationId": "putQbitCollaborationRecordsByTableByPkAssignment", + "parameters": [ + { + "description": "Parent table metadata name.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Parent record primary key.", + "in": "path", + "name": "pk", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationAssignmentRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationAssignmentV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Set record owner and assignee", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/collaboration/my-work": { + "get": { + "description": "Get my work summary. Uses the signed-in caller's permissions and record visibility.", + "operationId": "getQbitCollaborationMyWork", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollaborationMyWorkV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found (including invisible parents)" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Get my work summary", + "tags": [ + "collaboration" + ] + } + }, + "/qqq/v1/qbit/data-analysis/saved/{id}/run": { + "post": { + "description": "Re-run a visible saved analysis as the signed-in viewer. Requires saved READ and source READ/Analyze. Drops unavailable fields with a warning and returns the result typed by kind; inaccessible required axes or predicates produce no result.", + "operationId": "postQbitDataAnalysisSavedByIdRun", + "parameters": [ + { + "description": "Owner-scoped analysis run or watch id.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisSavedResultV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Run a saved analysis", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/saved": { + "get": { + "description": "List core-visible saved analyses with name, kind, source table label, owner, shared state, this viewer's starred flag and last update.", + "operationId": "getQbitDataAnalysisSaved", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisSavedListV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "List visible saved analyses", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/saved/{id}/star": { + "delete": { + "description": "Remove the signed-in user's star on a visible saved analysis. Idempotent; uses standard saved delete permission and owner locks.", + "operationId": "deleteQbitDataAnalysisSavedByIdStar", + "parameters": [ + { + "description": "Owner-scoped analysis run or watch id.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisStarV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Unstar a saved analysis", + "tags": [ + "data-analysis" + ] + }, + "put": { + "description": "Star a visible saved analysis for the signed-in user. Idempotent; uses standard saved insert permission and the personal star record lock.", + "operationId": "putQbitDataAnalysisSavedByIdStar", + "parameters": [ + { + "description": "Owner-scoped analysis run or watch id.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisStarV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Star a saved analysis", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/tables/{table}/sql": { + "post": { + "description": "Execute a typed analysis as the viewer and capture the main RDBMS aggregate SQL from core QueryStat. Requires installed SQL Workbench and its access permission. Non-RDBMS backends report unavailable; SQL is for reading and record security remains enforced at runtime.", + "operationId": "postQbitDataAnalysisTablesByTableSql", + "parameters": [ + { + "description": "QQQ table name to analyze.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisSavedRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisSqlV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Read an analysis aggregate SQL statement", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/export": { + "post": { + "description": "Execute a typed analysis as the signed-in viewer and download its result table as CSV or XLSX. Requires source READ/Analyze and FULL fields; uses core report formats.", + "operationId": "postQbitDataAnalysisExport", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisSavedRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisFileV1" + } + }, + "text/csv": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisFileV1" + } + } + }, + "description": "Analysis result file" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Export an analysis result", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/saved/{id}/export": { + "get": { + "description": "Re-run a visible saved analysis as the viewer, applying current source permissions and dropping unavailable fields, then download its result table as CSV or XLSX.", + "operationId": "getQbitDataAnalysisSavedByIdExport", + "parameters": [ + { + "description": "Visible saved analysis id.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "description": "Result file format.", + "in": "query", + "name": "format", + "required": true, + "schema": { + "enum": [ + "csv", + "xlsx" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisFileV1" + } + }, + "text/csv": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisFileV1" + } + } + }, + "description": "Analysis result file" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Export a saved analysis", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/tables/{table}/capabilities": { + "get": { + "description": "Discover whether the current user can analyze this table, readable fields, chart defaults, limits and backend capabilities.", + "operationId": "getQbitDataAnalysisTablesByTableCapabilities", + "parameters": [ + { + "description": "QQQ table name to analyze.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisCapabilitiesV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Check analysis availability", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/tables/{table}/column-profile": { + "post": { + "description": "Profile one column of a table under a filter: counts, nulls, distinct values, top values, numeric statistics and histogram, date patterns; every number has a drill-through filter unless privacy suppresses it.", + "operationId": "postQbitDataAnalysisTablesByTableColumnProfile", + "parameters": [ + { + "description": "QQQ table name to analyze.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisColumnProfileRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisColumnProfileV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Profile one column", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/tables/{table}/distinct-values": { + "post": { + "description": "Page through distinct stored values with display labels, counts and drill-through filters; search narrows stored values.", + "operationId": "postQbitDataAnalysisTablesByTableDistinctValues", + "parameters": [ + { + "description": "QQQ table name to analyze.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisDistinctValuesRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisDistinctValuesPageV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "List distinct column values", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/tables/{table}/compare": { + "post": { + "description": "Compare filtered A with filtered B (null means the whole permitted table). Return means, medians or category shares, B-minus-A deltas, valid significance tests and count-equivalent drills. Only FULL fields are accepted.", + "operationId": "postQbitDataAnalysisTablesByTableCompare", + "parameters": [ + { + "description": "QQQ table name to analyze.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisCompareRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisCompareV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Compare two populations", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/tables/{table}/shift": { + "post": { + "description": "Compare category shares or numeric quartiles across session-timezone calendar buckets. Compute descriptive PSI between the first and last complete nonempty buckets using fixed categories or baseline quartile bins.", + "operationId": "postQbitDataAnalysisTablesByTableShift", + "parameters": [ + { + "description": "QQQ table name to analyze.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisShiftRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisShiftV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Measure distribution shift over time", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/tables/{table}/correlation": { + "post": { + "description": "Compute a Pearson correlation matrix for 2 to 12 distinct FULL numeric fields, using paired non-null records. Every cell includes n and parameters for the scatter endpoint; core pushes down CORR or uses bounded streaming.", + "operationId": "postQbitDataAnalysisTablesByTableCorrelation", + "parameters": [ + { + "description": "QQQ table name to analyze.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisCorrelationRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisCorrelationV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Find numeric relationships", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/tables/{table}/scatter": { + "post": { + "description": "Return at most 2000 paired numeric points as the user, ordered by primary key when core query sampling is unavailable, plus a least-squares line fitted to the sample. Privacy disables individual drills and suppresses small populations.", + "operationId": "postQbitDataAnalysisTablesByTableScatter", + "parameters": [ + { + "description": "QQQ table name to analyze.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisScatterRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisScatterV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Inspect a numeric relationship", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/tables/{table}/crosstab": { + "post": { + "description": "Count combinations of two FULL fields with row and column shares, up to 20 categories per axis plus Other. Test independence using chi-square and Cramer V after pooling low expected counts; privacy suppresses small cells and their drills.", + "operationId": "postQbitDataAnalysisTablesByTableCrosstab", + "parameters": [ + { + "description": "QQQ table name to analyze.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisCrosstabRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisCrosstabV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Cross-tabulate two fields", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/watches/{id}/preview": { + "post": { + "description": "Compute complete time buckets and a detector verdict under the signed-in user's READ, Analyze and FULL-field permissions. Includes a baseline band annotation. Does not update the watch or raise alerts.", + "operationId": "postQbitDataAnalysisWatchesByIdPreview", + "parameters": [ + { + "description": "Owner-scoped analysis run or watch id.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisWatchPreviewV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Preview an anomaly watch", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/tables/{table}/pivot": { + "post": { + "description": "Group records by up to 3 row and 2 column fields (with date or numeric buckets) and compute counts, sums, averages, min/max, distinct counts or percentiles per cell; every cell has a drill-through filter.", + "operationId": "postQbitDataAnalysisTablesByTablePivot", + "parameters": [ + { + "description": "QQQ table name to analyze.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisPivotRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisPivotV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Explore a pivot table", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/tables/{table}/table-profile": { + "post": { + "description": "Profile readable fields under a filter for completeness, uniqueness, constant or empty columns and candidate keys.", + "operationId": "postQbitDataAnalysisTablesByTableTableProfile", + "parameters": [ + { + "description": "QQQ table name to analyze.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisTableProfileRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisTableProfileV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Profile table completeness and keys", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/tables/{table}/duplicates": { + "post": { + "description": "Group matching records by the selected readable fields and return repeated tuples with counts and drill-through filters.", + "operationId": "postQbitDataAnalysisTablesByTableDuplicates", + "parameters": [ + { + "description": "QQQ table name to analyze.", + "in": "path", + "name": "table", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisDuplicatesRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisDuplicatesResultV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Find duplicate groups", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/runs": { + "post": { + "description": "Start an owner-scoped exact column or table profile. Poll the returned runId until COMPLETE or FAILED; results honor the current session permissions.", + "operationId": "postQbitDataAnalysisRuns", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisStartRunRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisRunStartedV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Start an exact profile run", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/data-analysis/runs/{runId}": { + "get": { + "description": "Read status, timestamps and the typed columnProfile or tableProfile result of an owner-scoped run. Completed results are rechecked against current permissions.", + "operationId": "getQbitDataAnalysisRunsByRunId", + "parameters": [ + { + "description": "Owner-scoped analysis run or watch id.", + "in": "path", + "name": "runId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataAnalysisRunStatusV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Get an exact profile run", + "tags": [ + "data-analysis" + ] + } + }, + "/qqq/v1/qbit/db-performance/overview": { + "get": { + "description": "Requires db_performance.view and uses the caller's session.", + "operationId": "dbPerformanceOverview", + "parameters": [ + { + "description": "Configured monitored backend; defaults to the qbit backend.", + "in": "query", + "name": "backend", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceOverviewV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceErrorV1" + } + } + }, + "description": "Invalid request" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceErrorV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceErrorV1" + } + } + }, + "description": "Permission denied" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + } + ], + "summary": "Database Performance overview" + } + }, + "/qqq/v1/qbit/db-performance/activity": { + "get": { + "description": "Requires db_performance.view and uses the caller's session.", + "operationId": "dbPerformanceActivity", + "parameters": [ + { + "description": "Configured monitored backend; defaults to the qbit backend.", + "in": "query", + "name": "backend", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceActivityV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceErrorV1" + } + } + }, + "description": "Invalid request" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceErrorV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceErrorV1" + } + } + }, + "description": "Permission denied" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + } + ], + "summary": "Database Performance activity" + } + }, + "/qqq/v1/qbit/db-performance/explain": { + "post": { + "description": "PLAN requires db_performance.explain; ANALYZE requires db_performance.explain_analyze. Values and ANALYZE plans are never persisted.", + "operationId": "dbPerformanceExplain", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceExplainRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceExplainResultV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceErrorV1" + } + } + }, + "description": "Invalid request" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceErrorV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceErrorV1" + } + } + }, + "description": "Permission denied" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + } + ], + "summary": "Explain a PostgreSQL query" + } + }, + "/qqq/v1/qbit/db-performance/statements/lookup": { + "get": { + "description": "Requires db_performance.view and uses the caller's session.", + "operationId": "dbPerformanceLookup", + "parameters": [ + { + "description": "Configured monitored backend; defaults to the qbit backend.", + "in": "query", + "name": "backend", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sql", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceLookupV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceErrorV1" + } + } + }, + "description": "Invalid request" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceErrorV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DbPerformanceErrorV1" + } + } + }, + "description": "Permission denied" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + } + ], + "summary": "Database Performance lookup" + } + }, + "/qqq/v1/qbit/edi/guides/{guideId}/tree": { + "get": { + "description": "Read the guide tree. Uses the caller session and table read permissions. Preview also requires edi.map.preview. Rule writes use core table CRUD.", + "operationId": "getQbitEdiGuidesByGuideIdTree", + "parameters": [ + { + "description": "Positive record identifier.", + "in": "path", + "name": "guideId", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EdiGuideTreeV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid request or sample exceeds 5 MiB" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible record" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "413": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Host HTTP request size limit exceeded" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Read the guide tree", + "tags": [ + "edi" + ] + } + }, + "/qqq/v1/qbit/edi/maps/{mapId}/target": { + "get": { + "description": "Read target metadata and map rules. Uses the caller session and table read permissions. Preview also requires edi.map.preview. Rule writes use core table CRUD.", + "operationId": "getQbitEdiMapsByMapIdTarget", + "parameters": [ + { + "description": "Positive record identifier.", + "in": "path", + "name": "mapId", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EdiTargetV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid request or sample exceeds 5 MiB" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible record" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "413": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Host HTTP request size limit exceeded" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Read target metadata and map rules", + "tags": [ + "edi" + ] + } + }, + "/qqq/v1/qbit/edi/sandbox/preview": { + "post": { + "description": "Preview an encrypted sample with optional unsaved rules. Uses the caller session and table read permissions. Preview also requires edi.map.preview. Rule writes use core table CRUD.", + "operationId": "postQbitEdiSandboxPreview", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EdiPreviewRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EdiPreviewV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid request or sample exceeds 5 MiB" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible record" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "413": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Host HTTP request size limit exceeded" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Preview an encrypted sample with optional unsaved rules", + "tags": [ + "edi" + ] + } + }, + "/qqq/v1/qbit/edi/maps/{mapId}/validate": { + "post": { + "description": "Validate unsaved map rules. Uses the caller session and table read permissions. Preview also requires edi.map.preview. Rule writes use core table CRUD.", + "operationId": "postQbitEdiMapsByMapIdValidate", + "parameters": [ + { + "description": "Positive record identifier.", + "in": "path", + "name": "mapId", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EdiValidateRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EdiValidationV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid request or sample exceeds 5 MiB" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible record" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "413": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Host HTTP request size limit exceeded" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Validate unsaved map rules", + "tags": [ + "edi" + ] + } + }, + "/qqq/v1/qbit/qa-capture/capability": { + "get": { + "description": "Whether QA capture is on for the signed-in user and why, the provider settings, sanitizer rules, blur selectors, Content-Security-Policy origins and server context. Requires a session; a user without access gets enabled=false, never 403.", + "operationId": "qaCaptureCapability", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QaCaptureCapabilityV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QaCaptureErrorV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QaCaptureErrorV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QaCaptureErrorV1" + } + } + }, + "description": "QA capture is not enabled for this user" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + } + ], + "summary": "Read the QA capture capability" + } + }, + "/qqq/v1/qbit/qa-capture/report": { + "post": { + "description": "Stores the report (page, app, table, record, process, recent request ids, client build) with the user, environment, backend version, node and provider filled in by the server, and returns its reference and the recorder parameters.", + "operationId": "qaCaptureReportCreate", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QaCaptureReportRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QaCaptureReportResultV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QaCaptureErrorV1" + } + } + }, + "description": "Invalid input" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QaCaptureErrorV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QaCaptureErrorV1" + } + } + }, + "description": "QA capture is not enabled for this user" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + } + ], + "summary": "Create a QA report" + } + }, + "/qqq/v1/qbit/quick-search/status": { + "get": { + "description": "Requires Quick Search admin permission. Five-second instance cache; two-second refresh wait. Counts are saved diagnostics, not live source scans. Unknown values are null. Backlog counts are lower bounds when backlogTruncated is true.", + "operationId": "getQuickSearchStatus", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QuickSearchStatusV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Diagnostic rate limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Quick Search admin permission required" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Get Quick Search status", + "tags": [ + "quick-search" + ] + } + }, + "/qqq/v1/qbit/quick-search/suggest": { + "get": { + "description": "Requires a signed-in session, not Quick Search admin permission. Results inherit table READ permissions, configured record security locks and protected-field exclusions. One bounded candidate batch per table; no extra scans. Unavailable search and normalized terms shorter than two characters return empty groups.", + "operationId": "getQuickSearchSuggestions", + "parameters": [ + { + "description": "Search text: trim and collapse whitespace before applying the 2..100 character range. Shorter terms return empty groups; longer terms return 400.", + "in": "query", + "name": "q", + "required": true, + "schema": { + "description": "Normalized search term.", + "nullable": false, + "type": "string" + } + }, + { + "description": "Items per table: integer 1..10, default 5.", + "in": "query", + "name": "limitPerTable", + "required": false, + "schema": { + "description": "Maximum items per table; default 5, maximum 10.", + "nullable": false, + "type": "integer" + } + }, + { + "description": "Groups to return: integer 1..20, default 8.", + "in": "query", + "name": "maxTables", + "required": false, + "schema": { + "description": "Maximum groups; default 8, maximum 20.", + "nullable": false, + "type": "integer" + } + }, + { + "description": "Optional comma-separated table metadata names. Unknown, disabled and unreadable tables are omitted.", + "in": "query", + "name": "tables", + "required": false, + "schema": { + "description": "Table-name filter; omitted means all eligible tables.", + "nullable": false, + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QuickSearchSuggestV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing q, normalized term longer than 100 characters, or invalid limits" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Session permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Get Quick Search suggestions", + "tags": [ + "quick-search" + ] + } + }, + "/qqq/v1/qbit/release-notes/releases": { + "get": { + "description": "Published releases visible to the signed-in user, newest first, with their customer-facing items and whether each is new to the user.", + "operationId": "releaseNotesReleases", + "parameters": [ + { + "description": "Releases per page (1-50, default 20).", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Releases to skip (default 0).", + "in": "query", + "name": "offset", + "required": false, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseNotesReleasesV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseNotesErrorV1" + } + } + }, + "description": "Invalid request" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseNotesErrorV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Published release notes", + "tags": [ + "release-notes" + ] + } + }, + "/qqq/v1/qbit/release-notes/summary": { + "get": { + "description": "How many published releases are new to the signed-in user, and the latest one, for a menu badge.", + "operationId": "releaseNotesSummary", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseNotesSummaryV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseNotesErrorV1" + } + } + }, + "description": "Invalid request" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseNotesErrorV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "What's new summary", + "tags": [ + "release-notes" + ] + } + }, + "/qqq/v1/qbit/release-notes/seen": { + "post": { + "description": "Clears the signed-in user's new indicator. Takes no body.", + "operationId": "releaseNotesSeen", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseNotesSeenV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseNotesErrorV1" + } + } + }, + "description": "Invalid request" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseNotesErrorV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Mark What's new as seen", + "tags": [ + "release-notes" + ] + } + }, + "/qqq/v1/qbit/secured-data/reveal": { + "post": { + "operationId": "postQbitSecuredDataReveal", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SecuredDataRevealRequestV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SecuredDataRevealResponseV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid reveal request" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Reveal denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Record not found or locked" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Daily reveal cap reached" + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Reveal", + "tags": [ + "secured-data" + ] + } + }, + "/qqq/v1/qbit/secured-data/reveal/options": { + "get": { + "operationId": "getQbitSecuredDataRevealOptions", + "parameters": [ + { + "in": "query", + "name": "tableName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "fieldName", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SecuredDataRevealOptionsResponseV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "RevealOptions", + "tags": [ + "secured-data" + ] + } + }, + "/qqq/v1/qbit/secured-data/status": { + "get": { + "operationId": "getQbitSecuredDataStatus", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SecuredDataStatusResponseV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "The user (or the credential's scope) may not do this (code PERMISSION_DENIED)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Not found, or not visible to this user (code NOT_FOUND)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT)." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Status", + "tags": [ + "secured-data" + ] + } + }, + "/qqq/v1/sql-workbench/capabilities": { + "get": { + "description": "Get caller capabilities and configured limits. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchGetCapabilities", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchCapabilitiesV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Get caller capabilities and configured limits", + "tags": [ + "sql-workbench" + ] + } + }, + "/qqq/v1/sql-workbench/schema/{backendName}": { + "get": { + "description": "Inspect a target backend schema. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchGetSchema", + "parameters": [ + { + "description": "Configured target backend name.", + "in": "path", + "name": "backendName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "True to bypass the schema cache; default false.", + "in": "query", + "name": "refresh", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchSchemaV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Inspect a target backend schema", + "tags": [ + "sql-workbench" + ] + } + }, + "/qqq/v1/sql-workbench/execute": { + "post": { + "description": "Execute read-only SQL or preview and confirm a gated write. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchExecute", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchExecuteRequestV1" + } + } + }, + "required": false + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchExecutionV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Execute read-only SQL or preview and confirm a gated write", + "tags": [ + "sql-workbench" + ] + } + }, + "/qqq/v1/sql-workbench/explain": { + "post": { + "description": "Explain SQL; ANALYZE remains subject to write gates. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchExplain", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchExplainRequestV1" + } + } + }, + "required": false + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchExplainV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Explain SQL; ANALYZE remains subject to write gates", + "tags": [ + "sql-workbench" + ] + } + }, + "/qqq/v1/sql-workbench/executions/{uuid}/rows": { + "get": { + "description": "Page or sort the caller's cached result. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchGetRows", + "parameters": [ + { + "description": "Execution UUID; case insensitive.", + "in": "path", + "name": "uuid", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Rows to skip; default zero; negative values become zero.", + "in": "query", + "name": "offset", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Page size; nonpositive or absent uses the default. Rows cap at maxPageSize; history caps at 200 (default 50).", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Optional zero-based result column index.", + "in": "query", + "name": "sort", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Sort direction: desc (case insensitive) or asc (default).", + "in": "query", + "name": "dir", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchRowsV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Page or sort the caller's cached result", + "tags": [ + "sql-workbench" + ] + } + }, + "/qqq/v1/sql-workbench/executions/{uuid}/cancel": { + "post": { + "description": "Cancel the caller's running execution. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchCancelExecution", + "parameters": [ + { + "description": "Execution UUID; case insensitive.", + "in": "path", + "name": "uuid", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchEmptyRequestV1" + } + } + }, + "required": false + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchCancelledV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Cancel the caller's running execution", + "tags": [ + "sql-workbench" + ] + } + }, + "/qqq/v1/sql-workbench/history": { + "get": { + "description": "List the caller's recent audited executions. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchGetHistory", + "parameters": [ + { + "description": "Page size; nonpositive or absent uses the default. Rows cap at maxPageSize; history caps at 200 (default 50).", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Configured target backend name.", + "in": "query", + "name": "backendName", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchHistoryV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "List the caller's recent audited executions", + "tags": [ + "sql-workbench" + ] + } + }, + "/qqq/v1/sql-workbench/notebooks": { + "get": { + "description": "List visible personal or shared notebooks. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchListNotebooks", + "parameters": [ + { + "description": "mine (default) or shared notebook library.", + "in": "query", + "name": "scope", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchNotebooksV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "List visible personal or shared notebooks", + "tags": [ + "sql-workbench" + ] + }, + "post": { + "description": "Create a personal notebook. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchCreateNotebook", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchNotebookRequestV1" + } + } + }, + "required": false + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchNotebookV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Create a personal notebook", + "tags": [ + "sql-workbench" + ] + } + }, + "/qqq/v1/sql-workbench/notebooks/{id}": { + "delete": { + "description": "Delete an owned notebook. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchDeleteNotebook", + "parameters": [ + { + "description": "Notebook identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchDeletedV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Delete an owned notebook", + "tags": [ + "sql-workbench" + ] + }, + "get": { + "description": "Get a visible notebook and its cells. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchGetNotebook", + "parameters": [ + { + "description": "Notebook identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchNotebookV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Get a visible notebook and its cells", + "tags": [ + "sql-workbench" + ] + }, + "put": { + "description": "Update an owned notebook and record a version. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchUpdateNotebook", + "parameters": [ + { + "description": "Notebook identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchNotebookRequestV1" + } + } + }, + "required": false + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchNotebookV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Update an owned notebook and record a version", + "tags": [ + "sql-workbench" + ] + } + }, + "/qqq/v1/sql-workbench/notebooks/{id}/publish": { + "post": { + "description": "Publish or withdraw an owned notebook with share permission. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchPublishNotebook", + "parameters": [ + { + "description": "Notebook identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchPublishRequestV1" + } + } + }, + "required": false + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchNotebookV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Publish or withdraw an owned notebook with share permission", + "tags": [ + "sql-workbench" + ] + } + }, + "/qqq/v1/sql-workbench/notebooks/{id}/duplicate": { + "post": { + "description": "Make a personal copy of a visible notebook. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchDuplicateNotebook", + "parameters": [ + { + "description": "Notebook identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchEmptyRequestV1" + } + } + }, + "required": false + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchNotebookV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Make a personal copy of a visible notebook", + "tags": [ + "sql-workbench" + ] + } + }, + "/qqq/v1/sql-workbench/notebooks/{id}/versions": { + "get": { + "description": "List versions of a visible notebook. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchListVersions", + "parameters": [ + { + "description": "Notebook identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchVersionsV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "List versions of a visible notebook", + "tags": [ + "sql-workbench" + ] + } + }, + "/qqq/v1/sql-workbench/notebooks/{id}/versions/{n}": { + "get": { + "description": "Get a visible notebook version and saved content. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchGetVersion", + "parameters": [ + { + "description": "Notebook identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "description": "Notebook version number.", + "in": "path", + "name": "n", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchVersionV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Get a visible notebook version and saved content", + "tags": [ + "sql-workbench" + ] + } + }, + "/qqq/v1/sql-workbench/notebooks/{id}/versions/{n}/restore": { + "post": { + "description": "Restore an owned notebook version as a new version. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchRestoreVersion", + "parameters": [ + { + "description": "Notebook identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "description": "Notebook version number.", + "in": "path", + "name": "n", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchEmptyRequestV1" + } + } + }, + "required": false + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchNotebookV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Restore an owned notebook version as a new version", + "tags": [ + "sql-workbench" + ] + } + }, + "/qqq/v1/sql-workbench/notebooks/{id}/snapshots": { + "get": { + "description": "List snapshots of a visible notebook. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchListSnapshots", + "parameters": [ + { + "description": "Notebook identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchSnapshotsV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "List snapshots of a visible notebook", + "tags": [ + "sql-workbench" + ] + }, + "post": { + "description": "Pin the caller's cached result to an owned notebook. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchCreateSnapshot", + "parameters": [ + { + "description": "Notebook identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchSnapshotRequestV1" + } + } + }, + "required": false + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchSnapshotV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Pin the caller's cached result to an owned notebook", + "tags": [ + "sql-workbench" + ] + } + }, + "/qqq/v1/sql-workbench/notebooks/{id}/snapshots/{snapshotId}": { + "delete": { + "description": "Delete a snapshot from an owned notebook. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchDeleteSnapshot", + "parameters": [ + { + "description": "Notebook identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "description": "Snapshot identifier.", + "in": "path", + "name": "snapshotId", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchDeletedV1" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Delete a snapshot from an owned notebook", + "tags": [ + "sql-workbench" + ] + } + }, + "/qqq/v1/sql-workbench/executions/{uuid}/export": { + "get": { + "description": "Export the caller's cached result as CSV, JSON or XLSX. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit.", + "operationId": "sqlWorkbenchExportResult", + "parameters": [ + { + "description": "Execution UUID; case insensitive.", + "in": "path", + "name": "uuid", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "csv (default), json or xlsx; case insensitive.", + "in": "query", + "name": "format", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchExportJsonV1" + } + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchExportFileV1" + } + }, + "text/csv; charset=utf-8": { + "schema": { + "$ref": "#/components/schemas/SqlWorkbenchExportFileV1" + } + } + }, + "description": "Attachment named sql-result-{short UUID}.{format}; Cache-Control: no-store" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Invalid input or execution limit exceeded" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Sign in required" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Permission denied" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Missing or invisible resource" + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Execution UUID already used" + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BasicErrorResponseV1" + } + } + }, + "description": "Too many requests (code RATE_LIMITED); retry later." + } + }, + "security": [ + { + "sessionUuidCookie": [ + "N/A" + ] + }, + { + "bearerAuth": [ + "N/A" + ] + }, + { + "oauth2": [ + "openid", + "profile", + "email" + ] + } + ], + "summary": "Export the caller's cached result as CSV, JSON or XLSX", + "tags": [ + "sql-workbench" + ] + } + } + }, + "components": { + "schemas": { + "AppMetaData": { + "type": "object", + "properties": { + "childMap": { + "type": "object", + "description": "Map of other apps, tables, process, and reports, which are contained within this app. Same contents as the children list, just structured as a map.", + "additionalProperties": { + "$ref": "#/components/schemas/AppTreeNode" + } + }, + "children": { + "type": "array", + "description": "List of other apps, tables, process, and reports, which are contained within this app.", + "items": { + "$ref": "#/components/schemas/AppTreeNode" + } + }, + "helpContents": { + "type": "object", + "description": "Help entries by slot, filtered for the current session.", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + } + }, + "icon": { + "description": "Icon to display for the app.", + "$ref": "#/components/schemas/Icon" + }, + "keywords": { + "type": "array", + "description": "Search aliases (old labels, jargon, vendor names); match search on label, keywords and ancestor labels; never display", + "items": { + "type": "string" + } + }, + "label": { + "type": "string", + "description": "User-facing name for this app" + }, + "name": { + "type": "string", + "description": "Unique name for this app within the QQQ Instance" + }, + "sections": { + "type": "array", + "description": "List of sections - sub-divisions of the app, to further organize its children.", + "items": { + "$ref": "#/components/schemas/AppSection" + } + }, + "supplementalAppMetaData": { + "type": "object", + "description": "Additional meta-data describing the app, which may not be known to the QQQ backend core module." + }, + "widgets": { + "type": "array", + "description": "List of widgets names that are part of this app. These strings should be keys to the widgets map in the QQQ Instance.", + "items": { + "type": "string" + } + } + } + }, + "AppSection": { + "type": "object", + "properties": { + "apps": { + "type": "array", + "description": "List of child app names for the section", + "items": { + "type": "string" + } + }, + "collapsedByDefault": { + "type": "boolean", + "description": "Whether the section is collapsed by default; SETTINGS defaults to true", + "nullable": true + }, + "icon": { + "description": "Icon to display for the section.", + "$ref": "#/components/schemas/Icon" + }, + "label": { + "type": "string", + "description": "User-facing name of the section." + }, + "name": { + "type": "string", + "description": "Unique (within the app) name for this section." + }, + "processes": { + "type": "array", + "description": "List of process names for the section", + "items": { + "type": "string" + } + }, + "reports": { + "type": "array", + "description": "List of report names for the section", + "items": { + "type": "string" + } + }, + "role": { + "type": "string", + "description": "PRIMARY: items shown without a heading; HISTORY: system-written records under a heading; SETTINGS: configuration under a heading, collapsed by default; GROUP: a heading grouping child apps, never navigable", + "enum": [ + "PRIMARY", + "HISTORY", + "SETTINGS", + "GROUP" + ] + }, + "tables": { + "type": "array", + "description": "List of table names for the section", + "items": { + "type": "string" + } + } + } + }, + "AppTreeNode": { + "type": "object", + "properties": { + "children": { + "type": "array", + "description": "Child elements. Only applies for type='app', which contains additional apps under it", + "items": { + "$ref": "#/components/schemas/AppTreeNode" + } + }, + "icon": { + "description": "Icon to display for the item.", + "$ref": "#/components/schemas/Icon" + }, + "keywords": { + "type": "array", + "description": "Search aliases (old labels, jargon, vendor names); match search on label, keywords and ancestor labels; never display", + "items": { + "type": "string" + } + }, + "label": { + "type": "string", + "description": "User-facing name of the element." + }, + "name": { + "type": "string", + "description": "Unique (within its type) name for this element. e.g., for type = 'table', the table's name." + }, + "type": { + "type": "string", + "description": "The type of node (table, process, report, app)" + } + } + }, + "AssociatedScriptMetaData": { + "type": "object", + "properties": { + "fieldName": { + "type": "string", + "description": "Name of the field, in the record's table, that references the script." + }, + "scriptTypeId": { + "type": "object", + "description": "Id of the script type (a scriptType record) of the scripts this field references." + } + } + }, + "Association": { + "type": "object", + "properties": { + "associatedTableName": { + "type": "string", + "description": "Name of the associated table; its permissions remain independent" + }, + "join": { + "type": "object", + "description": "The named join and field pairs defining this association", + "properties": { + "joinOns": { + "type": "array" + }, + "leftTable": { + "type": "string" + }, + "name": { + "type": "string" + }, + "orderBys": { + "type": "array" + }, + "rightTable": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "ONE_TO_ONE", + "ONE_TO_MANY", + "MANY_TO_ONE", + "MANY_TO_MANY" + ] + } + } + }, + "name": { + "type": "string", + "description": "Exact name used for this group in associatedRecords" + } + } + }, + "AuditsCapabilityV1": { + "type": "object", + "properties": { + "available": { + "type": "boolean", + "description": "True when the user can read this table and its audits one of the two ways (the audit process enforces both). Independent of level: records of a table at level NONE can still have audits written explicitly.", + "nullable": true + }, + "detailTableName": { + "type": "string", + "description": "The audit detail table (field changes), joined to tableName." + }, + "level": { + "type": "string", + "description": "The table's audit level: NONE, RECORD or FIELD (informational: what is audited automatically)." + }, + "processName": { + "type": "string", + "description": "The process that returns a record's audits (inputs tableName, recordId); absent when the user may not run it." + }, + "tableName": { + "type": "string", + "description": "The audit table, when the user may query it directly." + } + } + }, + "AuthenticationMetaDataResponseV1": { + "type": "object", + "properties": { + "branding": { + "type": "object", + "description": "The application's branding that is safe to show before sign-in (names, logo, icon and accent colors; never\nbanners), so a login page can look like the application. Absent when the instance defines no branding.", + "properties": { + "accentColor": { + "type": "string", + "description": "Primary accent color, as a CSS color value." + }, + "accentColorLight": { + "type": "string", + "description": "Light variant of the accent color, as a CSS color value." + }, + "appName": { + "type": "string", + "description": "Name of this application, for display to users." + }, + "companyName": { + "type": "string", + "description": "Name of the company that operates this application." + }, + "icon": { + "type": "string", + "description": "Path or URL of the application's small icon image." + }, + "logo": { + "type": "string", + "description": "Path or URL of the application's logo image." + } + } + }, + "dashboardCspSources": { + "type": "object", + "description": "Optional public CSP source additions for standalone dashboards, derived from configured application features; never a full policy or inline script hashes.", + "properties": { + "connectSrc": { + "type": "array", + "description": "HTTP(S) connection sources required by configured features; no default policy sources.", + "items": { + "type": "string" + } + }, + "frameSrc": { + "type": "array", + "description": "Frame sources required by configured features.", + "items": { + "type": "string" + } + }, + "scriptSrc": { + "type": "array", + "description": "Script sources required by configured features; no inline hashes, nonces or unsafe keywords.", + "items": { + "type": "string" + } + }, + "styleSrc": { + "type": "array", + "description": "Style sources required by configured features.", + "items": { + "type": "string" + } + } + } + }, + "name": { + "type": "string", + "description": "Unique name for the authentication metaData object within the QInstance.\n" + }, + "type": { + "type": "string", + "description": "Specifier for the type of authentication module being used.\n\nFrontends should use this value to determine how to prompt the user for authentication credentials.\nIn addition, depending on this value, additional properties will be included in this object, as\nmay be needed to complete the authorization workflow with the provider (e.g., a baseUrl, clientId,\nand audience for an OAuth type workflow)." + }, + "values": { + "description": "Additional values, as determined by the type of authentication provider.\n", + "anyOf": [ + { + "type": "object", + "description": "No additional values are used for some authentication providers." + }, + { + "type": "object", + "description": "Additional values used by the Auth0 type authentication provider.", + "properties": { + "audience": { + "type": "string", + "description": "Audience for auth0" + }, + "baseUrl": { + "type": "string", + "description": "BaseUrl for auth0" + }, + "clientId": { + "type": "string", + "description": "ClientId for auth0" + } + } + }, + { + "type": "object", + "description": "Additional values used by the OAuth2 type authentication provider.", + "properties": { + "baseUrl": { + "type": "string", + "description": "BaseUrl for OAuth2 provider" + }, + "bearerTokensAccepted": { + "type": "boolean", + "description": "True when the server accepts the provider's access tokens as Authorization: Bearer . Since 1.6.0.", + "nullable": true + }, + "clientId": { + "type": "string", + "description": "ClientId for OAuth2 provider" + }, + "nativeClientBaseUrl": { + "type": "string", + "description": "The issuer (OIDC discovery base URL) of nativeClientId, when it differs from baseUrl. Since 1.6.0." + }, + "nativeClientId": { + "type": "string", + "description": "The public OAuth2 client for native clients (CLI, TUI, mobile): use it with auth-code + PKCE or the device-authorization grant, then send the access token as Authorization: Bearer. Absent when the app has no native client. Since 1.6.0." + }, + "scopes": { + "type": "string", + "description": "OAuth2 scopes to request (space-separated)" + } + } + } + ] + } + } + }, + "AvatarLookupRequestV1": { + "type": "object", + "description": "The users to look up.", + "properties": { + "userIds": { + "type": "array", + "description": "User ids (as in comments, presence and mentions); at most 200.", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "AvatarLookupResponseV1": { + "type": "object", + "description": "Avatar URLs by user id.", + "properties": { + "avatars": { + "type": "object", + "description": "User id to avatar URL (relative; add size=32|64|128|256). Users without an avatar are absent.", + "additionalProperties": { + "type": "string" + } + } + } + }, + "BackChannelLogoutResponseV1": { + "type": "object" + }, + "BasicErrorResponseV1": { + "description": "The error body of every UI API operation (core and extensions).", + "properties": { + "error": { + "description": "The error message (the same as message; kept for clients of UI API 1.0 to 1.5).", + "type": "string" + }, + "code": { + "description": "A stable, machine-readable code. Well-known values: BAD_REQUEST (400), UNAUTHENTICATED (401),\nPERMISSION_DENIED (403), NOT_FOUND (404), CONFLICT (409), RATE_LIMITED (429), INTERNAL_ERROR (500),\nERROR (other). Extensions may add codes; treat an unknown code by the HTTP status. Since 1.6.0.", + "type": "string" + }, + "message": { + "description": "A message to show the user. Since 1.6.0.", + "type": "string" + }, + "fieldErrors": { + "description": "Errors about particular request fields, when known. Since 1.6.0.", + "items": { + "properties": { + "field": { + "description": "The field (or parameter) name.", + "type": "string" + }, + "message": { + "description": "The error about that field.", + "type": "string" + }, + "code": { + "description": "An optional machine-readable code, e.g. REQUIRED, TOO_LONG, PATTERN.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "traceId": { + "description": "Identifies this request in the server logs (also the X-QQQ-Trace-Id response header); quote it when reporting a problem. Since 1.6.0.", + "type": "string" + } + }, + "type": "object" + }, + "Branding": { + "type": "object", + "properties": { + "accentColor": { + "type": "string", + "description": "Primary accent color, as a CSS color value." + }, + "accentColorLight": { + "type": "string", + "description": "Light variant of the accent color, as a CSS color value." + }, + "appName": { + "type": "string", + "description": "Name of this application, for display to users." + }, + "banners": { + "type": "object", + "description": "Banners to display, keyed by the slot where each is shown.", + "additionalProperties": { + "$ref": "#/components/schemas/BrandingBanner" + } + }, + "companyName": { + "type": "string", + "description": "Name of the company that operates this application." + }, + "companyUrl": { + "type": "string", + "description": "URL for the company's web site." + }, + "icon": { + "type": "string", + "description": "Path or URL of the application's small icon image." + }, + "logo": { + "type": "string", + "description": "Path or URL of the application's logo image." + } + } + }, + "BrandingBanner": { + "type": "object", + "properties": { + "additionalStyles": { + "type": "object", + "description": "Additional CSS style properties for the banner." + }, + "backgroundColor": { + "type": "string", + "description": "Background color, as a CSS color value." + }, + "messageHTML": { + "type": "string", + "description": "HTML message, used instead of the plain-text message when set." + }, + "messageText": { + "type": "string", + "description": "Plain-text message." + }, + "severity": { + "type": "string", + "description": "Severity of the message: INFO, WARNING, ERROR or SUCCESS." + }, + "textColor": { + "type": "string", + "description": "Text color, as a CSS color value." + } + } + }, + "BuiltInViewV1": { + "type": "object", + "properties": { + "filter": { + "type": "object", + "properties": { + "booleanOperator": { + "type": "string", + "enum": [ + "OR" + ] + }, + "criteria": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fieldName": { + "type": "string" + }, + "operator": { + "type": "string", + "enum": [ + "EQUALS" + ] + }, + "values": { + "type": "array", + "items": { + "type": "object", + "description": "The executing session's user id. Display as Me. A missing user matches nothing.", + "properties": { + "type": { + "type": "string", + "enum": [ + "CurrentUser" + ] + } + } + } + } + } + } + } + } + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "BulkLoadColumnProfile": { + "type": "object", + "properties": { + "classification": { + "type": "string", + "description": "Data classification of the mapped field (PUBLIC, CONFIDENTIAL, PII, PHI), or null." + }, + "columnIndex": { + "type": "number", + "description": "Zero-based column index in the file." + }, + "columnLetter": { + "type": "string", + "description": "Spreadsheet-style column letter (A, B, ... AA)." + }, + "distinctCount": { + "type": "number", + "description": "Distinct non-blank values counted (capped at 1000)." + }, + "distinctCountCapped": { + "type": "boolean", + "description": "Whether more distinct values exist than were counted.", + "nullable": true + }, + "header": { + "type": "string", + "description": "Header text (or Column A, Column B ... when the file has no header row)." + }, + "inferredType": { + "type": "string", + "description": "INTEGER, DECIMAL, BOOLEAN, DATE, DATE_TIME or STRING, from the profiled values." + }, + "mappedFieldName": { + "type": "string", + "description": "The table field the suggested mapping assigns this column to, or null." + }, + "maxLength": { + "type": "number", + "description": "Longest value length." + }, + "patternClass": { + "type": "string", + "description": "DATE_LIKE, EMAIL_LIKE, NUMERIC, CODE_LIKE, TEXT or EMPTY." + }, + "percentBlank": { + "type": "number", + "description": "Percent of profiled rows where the column is blank." + }, + "sampleValues": { + "type": "array", + "description": "Up to sampleCount distinct values, only when samplesAllowed; otherwise empty.", + "items": { + "type": "string" + } + }, + "samplesAllowed": { + "type": "boolean", + "description": "Whether sample values may be shown: an AI route of hipaa, or a mapped field that is unclassified or PUBLIC. Unmapped columns are treated as classified.", + "nullable": true + } + } + }, + "BulkLoadColumnRef": { + "type": "object", + "properties": { + "columnIndex": { + "type": "number", + "description": "Zero-based column index in the file." + }, + "header": { + "type": "string", + "description": "Header text." + } + } + }, + "BulkLoadFieldRef": { + "type": "object", + "properties": { + "fieldName": { + "type": "string", + "description": "Field name." + }, + "label": { + "type": "string", + "description": "Field label." + }, + "possibleValueSourceName": { + "type": "string", + "description": "Possible value source of the field, if any (its file values need mapping)." + } + } + }, + "BulkLoadRowError": { + "type": "object", + "properties": { + "errorCode": { + "type": "string", + "description": "VALUE_TYPE, POSSIBLE_VALUE, DUPLICATE, REQUIRED or OTHER." + }, + "fieldName": { + "type": "string", + "description": "The field the error is about, when known." + }, + "message": { + "type": "string", + "description": "The error message (value-free)." + }, + "rowNumbers": { + "type": "string", + "description": "File rows with the error, e.g. Row 3; Rows 7-9 (no values)." + } + } + }, + "BulkLoadSuggestMappingResponseV1": { + "type": "object", + "properties": { + "profile": { + "type": "object", + "description": "The suggested bulk load profile (v1: version, layout, hasHeaderRow, isBulkEdit, and fieldList entries of fieldName, columnIndex, headerName, defaultValue, doValueMapping, valueMappings, clearIfEmpty)." + }, + "unmappedColumns": { + "type": "array", + "description": "File columns the suggestion does not map.", + "items": { + "$ref": "#/components/schemas/BulkLoadColumnRef" + } + }, + "unmappedRequiredFields": { + "type": "array", + "description": "Required table fields the suggestion does not fill.", + "items": { + "$ref": "#/components/schemas/BulkLoadFieldRef" + } + }, + "valueMappingFields": { + "type": "array", + "description": "Mapped fields with a possible value source, whose file values may need mapping.", + "items": { + "$ref": "#/components/schemas/BulkLoadFieldRef" + } + } + } + }, + "BulkLoadSummaryLine": { + "type": "object", + "properties": { + "bulletsOfText": { + "type": "array", + "description": "Example rows (and their values, unless masked for a classified field).", + "items": { + "type": "string" + } + }, + "count": { + "type": "number", + "description": "Number of records the line describes." + }, + "message": { + "type": "string", + "description": "The standard process summary message." + }, + "status": { + "type": "string", + "description": "OK, INFO, WARNING or ERROR." + } + } + }, + "BulkLoadUploadProfileResponseV1": { + "type": "object", + "properties": { + "columns": { + "type": "array", + "description": "The columns.", + "items": { + "$ref": "#/components/schemas/BulkLoadColumnProfile" + } + }, + "fileName": { + "type": "string", + "description": "The uploaded file name." + }, + "hasHeaderRow": { + "type": "boolean", + "description": "Whether row 1 looks like a header row (the suggester maps at least one of its values).", + "nullable": true + }, + "rowsProfiled": { + "type": "number", + "description": "Data rows profiled (up to 1000)." + }, + "uploadRef": { + "type": "string", + "description": "The upload ref." + } + } + }, + "BulkLoadValidateResponseV1": { + "type": "object", + "properties": { + "errorCount": { + "type": "number", + "description": "Records with errors." + }, + "errors": { + "type": "array", + "description": "Error groups with row numbers (up to 100).", + "items": { + "$ref": "#/components/schemas/BulkLoadRowError" + } + }, + "jobId": { + "type": "number", + "description": "Reserved: a FULL run over the durable threshold will run as a VALIDATE job and return its id. Always null in this version." + }, + "mode": { + "type": "string", + "description": "SAMPLE (the first 100 rows) or FULL (the whole file)." + }, + "okCount": { + "type": "number", + "description": "Records that would be inserted." + }, + "previewRecordCount": { + "type": "number", + "description": "For SAMPLE, the rows validated." + }, + "processName": { + "type": "string", + "description": "The table's bulk-insert process the dry run used." + }, + "recordCount": { + "type": "number", + "description": "Records read from the file." + }, + "summaryLines": { + "type": "array", + "description": "The standard process summary lines.", + "items": { + "$ref": "#/components/schemas/BulkLoadSummaryLine" + } + } + } + }, + "DeliveryDestinationsResponseV1": { + "type": "object", + "properties": { + "destinations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "label": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "maxClassification": { + "type": "string" + }, + "aboveMaxClassification": { + "type": "string" + }, + "order": { + "type": "integer" + }, + "maxAttachmentBytes": { + "type": "integer", + "format": "int64" + }, + "allowBearerLinks": { + "type": "boolean" + } + } + } + } + } + }, + "DeliveryOutputResponseV1": { + "type": "string", + "format": "binary" + }, + "DeliveryTargetStepResponseV1": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "label": { + "type": "string" + }, + "options": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + } + } + } + }, + "freeText": { + "type": "boolean" + }, + "complete": { + "type": "boolean" + }, + "summary": { + "type": "string" + } + } + }, + "DeliveryTargetsRequestV1": { + "type": "object", + "properties": { + "chosen": { + "type": "object", + "description": "Selections by delivery target step name; values are provider-defined target identifiers.", + "additionalProperties": true + } + } + }, + "EsbCapabilities": { + "description": "What the provider supports for this destination - show only the actions that are true.", + "properties": { + "browse": { + "description": "Messages can be browsed.", + "type": "boolean" + }, + "pauseQueue": { + "description": "The queue can be paused and resumed.", + "type": "boolean" + }, + "purge": { + "description": "All messages can be deleted.", + "type": "boolean" + }, + "deleteSelected": { + "description": "Selected messages can be deleted.", + "type": "boolean" + }, + "deleteOlderThan": { + "description": "Messages older than a time can be deleted.", + "type": "boolean" + }, + "move": { + "description": "Messages can be moved to another destination.", + "type": "boolean" + } + }, + "type": "object" + }, + "EsbCounter": { + "description": "Activity counters since the server started.", + "properties": { + "published": { + "description": "Messages published.", + "type": "integer" + }, + "publishFailures": { + "description": "Publish attempts that failed.", + "type": "integer" + }, + "consumed": { + "description": "Messages consumed.", + "type": "integer" + }, + "succeeded": { + "description": "Consumed messages processed successfully.", + "type": "integer" + }, + "failed": { + "description": "Consumed messages that failed.", + "type": "integer" + }, + "retried": { + "description": "Redeliveries.", + "type": "integer" + }, + "deadLettered": { + "description": "Messages moved to the dead-letter destination.", + "type": "integer" + }, + "inFlight": { + "description": "Messages being processed now.", + "type": "integer" + }, + "lastActivity": { + "description": "Time of the last activity (ISO-8601), or null.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "avgMs": { + "description": "Average processing time in milliseconds.", + "type": "integer" + }, + "maxMs": { + "description": "Longest processing time in milliseconds.", + "type": "integer" + }, + "lastError": { + "description": "The last error message, or null.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "EsbDeadLetter": { + "description": "A dead-letter (or subscription) destination of a trigger.", + "properties": { + "brokerName": { + "description": "Name on the broker.", + "type": "string" + }, + "messageCount": { + "description": "Messages waiting, or null when unknown.", + "nullable": true, + "type": "integer" + }, + "paused": { + "description": "Whether it is paused, or null when unknown.", + "nullable": true, + "type": "boolean" + } + }, + "type": "object" + }, + "EsbDestination": { + "description": "A queue or topic.", + "properties": { + "name": { + "description": "Destination name.", + "type": "string" + }, + "type": { + "description": "Destination type.", + "enum": [ + "QUEUE", + "TOPIC" + ], + "type": "string" + }, + "provider": { + "description": "Name of the provider (broker connection).", + "type": "string" + }, + "brokerName": { + "description": "Name of the destination on the broker.", + "type": "string" + }, + "counters": { + "$ref": "#/components/schemas/EsbCounter" + }, + "queueInfo": { + "$ref": "#/components/schemas/EsbQueueInfo", + "nullable": true + }, + "capabilities": { + "$ref": "#/components/schemas/EsbCapabilities" + } + }, + "type": "object" + }, + "EsbMessage": { + "description": "A message on a destination.", + "properties": { + "messageId": { + "description": "Broker message id.", + "type": "string" + }, + "timestamp": { + "description": "When it was sent (ISO-8601).", + "format": "date-time", + "type": "string" + }, + "deliveryCount": { + "description": "Delivery attempts so far.", + "type": "integer" + }, + "event": { + "additionalProperties": true, + "description": "The CloudEvents envelope (specversion, id, source, type, time, subject, datacontenttype, data, qqqcausationid), or null when the body is not one.", + "nullable": true, + "type": "object" + }, + "rawBody": { + "description": "The message body as text.", + "type": "string" + }, + "properties": { + "additionalProperties": true, + "description": "Message properties.", + "type": "object" + } + }, + "type": "object" + }, + "EsbMessagePageResponseV1": { + "description": "A page of messages.", + "properties": { + "messages": { + "description": "The messages, oldest first.", + "items": { + "$ref": "#/components/schemas/EsbMessage" + }, + "type": "array" + }, + "hasMore": { + "description": "Whether more messages follow this page.", + "type": "boolean" + } + }, + "type": "object" + }, + "EsbOverviewDestination": { + "allOf": [ + { + "$ref": "#/components/schemas/EsbDestination" + }, + { + "properties": { + "publishers": { + "description": "Tables and processes publishing to it.", + "items": { + "$ref": "#/components/schemas/EsbPublisher" + }, + "type": "array" + }, + "triggers": { + "description": "Triggers consuming it.", + "items": { + "$ref": "#/components/schemas/EsbTrigger" + }, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "A destination with its publishers and triggers." + }, + "EsbOverviewResponseV1": { + "description": "GET /esb/overview: providers and every destination.", + "properties": { + "providers": { + "description": "Broker connections.", + "items": { + "$ref": "#/components/schemas/EsbProvider" + }, + "type": "array" + }, + "destinations": { + "description": "Destinations with their publishers and triggers.", + "items": { + "$ref": "#/components/schemas/EsbOverviewDestination" + }, + "type": "array" + }, + "permissions": { + "$ref": "#/components/schemas/EsbPermissions" + } + }, + "type": "object" + }, + "EsbPermissions": { + "description": "What the user may do.", + "properties": { + "canOperate": { + "description": "May pause, resume and retry.", + "type": "boolean" + }, + "canDelete": { + "description": "May delete messages.", + "type": "boolean" + } + }, + "type": "object" + }, + "EsbProcessResponseV1": { + "description": "GET /esb/process/{process}: what a process publishes, and the triggers that run it.", + "properties": { + "process": { + "description": "Process name.", + "type": "string" + }, + "publications": { + "description": "Destinations the process publishes to.", + "items": { + "$ref": "#/components/schemas/EsbPublication" + }, + "type": "array" + }, + "triggers": { + "description": "Triggers that run the process.", + "items": { + "$ref": "#/components/schemas/EsbTrigger" + }, + "type": "array" + }, + "permissions": { + "$ref": "#/components/schemas/EsbPermissions" + } + }, + "type": "object" + }, + "EsbProvider": { + "description": "A broker connection.", + "properties": { + "name": { + "description": "Provider name.", + "type": "string" + }, + "type": { + "description": "Broker type.", + "enum": [ + "ACTIVEMQ_ARTEMIS", + "RABBITMQ" + ], + "type": "string" + }, + "connected": { + "description": "Whether the connection is up.", + "type": "boolean" + }, + "managementEnabled": { + "description": "Whether broker management (browse, pause, purge) is available.", + "type": "boolean" + } + }, + "type": "object" + }, + "EsbPublication": { + "description": "A destination that a table or process publishes events to.", + "properties": { + "destination": { + "$ref": "#/components/schemas/EsbDestination" + }, + "events": { + "description": "Events published: INSERT, UPDATE or DELETE for tables; STARTED, COMPLETED or FAILED for processes.", + "items": { + "description": "Event name.", + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "EsbPublisher": { + "description": "A table or process that publishes to a destination.", + "properties": { + "kind": { + "description": "What publishes.", + "enum": [ + "TABLE", + "PROCESS" + ], + "type": "string" + }, + "name": { + "description": "Table or process name.", + "type": "string" + }, + "events": { + "description": "Events published.", + "items": { + "description": "Event name.", + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "EsbQueueInfo": { + "description": "Broker-reported state of a queue.", + "properties": { + "messageCount": { + "description": "Messages waiting.", + "type": "integer" + }, + "consumerCount": { + "description": "Connected consumers.", + "type": "integer" + }, + "paused": { + "description": "Whether the queue is paused.", + "type": "boolean" + } + }, + "type": "object" + }, + "EsbTableResponseV1": { + "description": "GET /esb/table/{table}: what a table publishes, and who subscribes.", + "properties": { + "table": { + "description": "Table name.", + "type": "string" + }, + "publications": { + "description": "Destinations the table publishes to.", + "items": { + "$ref": "#/components/schemas/EsbPublication" + }, + "type": "array" + }, + "subscribers": { + "description": "Triggers subscribed to those destinations (on processes the user can access).", + "items": { + "$ref": "#/components/schemas/EsbTrigger" + }, + "type": "array" + }, + "permissions": { + "$ref": "#/components/schemas/EsbPermissions" + } + }, + "type": "object" + }, + "EsbTrigger": { + "description": "A process subscribed to a destination.", + "properties": { + "name": { + "description": "Trigger name.", + "type": "string" + }, + "processName": { + "description": "Process the trigger runs.", + "type": "string" + }, + "processLabel": { + "description": "User-facing label of the process.", + "type": "string" + }, + "destination": { + "$ref": "#/components/schemas/EsbDestination" + }, + "mode": { + "description": "SINGLE runs the process per message; BATCH per batch of messages.", + "enum": [ + "SINGLE", + "BATCH" + ], + "type": "string" + }, + "concurrency": { + "description": "Consumers run in parallel.", + "type": "integer" + }, + "maxAttempts": { + "description": "Attempts before a message is dead-lettered.", + "type": "integer" + }, + "state": { + "description": "Current state of the trigger.", + "enum": [ + "RUNNING", + "PAUSED", + "CONNECTING", + "STOPPED" + ], + "type": "string" + }, + "counters": { + "$ref": "#/components/schemas/EsbCounter" + }, + "deadLetter": { + "$ref": "#/components/schemas/EsbDeadLetter" + }, + "subscription": { + "$ref": "#/components/schemas/EsbDeadLetter", + "nullable": true + } + }, + "type": "object" + }, + "ExposedJoin": { + "type": "object", + "properties": { + "isMany": { + "type": "boolean", + "description": "Whether or not this join is 'to many' in nature", + "nullable": true + }, + "joinPath": { + "type": "array", + "description": "A list of joins that travel from the base table to the exposed join table", + "items": { + "type": "object", + "properties": { + "joinOns": { + "type": "array" + }, + "leftTable": { + "type": "string" + }, + "name": { + "type": "string" + }, + "orderBys": { + "type": "array" + }, + "rightTable": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "ONE_TO_ONE", + "ONE_TO_MANY", + "MANY_TO_ONE", + "MANY_TO_MANY" + ] + } + } + } + }, + "joinTable": { + "description": "The meta-data for the joined table", + "$ref": "#/components/schemas/TableMetaData" + }, + "label": { + "type": "string", + "description": "User-facing label to display for this join" + } + } + }, + "FieldAdornment": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Type of this adornment", + "enum": [ + "LINK", + "CHIP", + "SIZE", + "CODE_EDITOR", + "RENDER_HTML", + "REVEAL", + "FILE_DOWNLOAD", + "FILE_UPLOAD", + "TOOLTIP", + "WIDGET", + "ERROR", + "FILE_PREVIEW" + ] + }, + "values": { + "type": "object", + "description": "Values associated with this adornment. Keys and the meanings of their values differ by type; the known\nkeys are listed (each names the type(s) it applies to). CHIP also uses pattern keys: `color.{fieldValue}`\n(one of default, info, primary, secondary, success, warning, error) and `icon.{fieldValue}` (an icon name),\ngiving the chip colour and icon for a field value. Clients ignore keys they do not know.", + "properties": { + "target": { + "type": "string", + "description": "LINK: where to open the link: _blank for a new window/tab; otherwise the same view." + }, + "toRecordFromTable": { + "type": "string", + "description": "LINK: the field value is a primary key of this table; link to that record (a client navigates to the record view)." + }, + "toRecordFromTableDynamic": { + "type": "boolean", + "description": "LINK: the target table is per record - read it from the record displayValue `{fieldName}:toRecordFromTableDynamic`." + }, + "fileNameField": { + "type": "string", + "description": "FILE_DOWNLOAD, FILE_PREVIEW: the field holding the file name to save or show." + }, + "defaultExtension": { + "type": "string", + "description": "FILE_DOWNLOAD: extension for the saved file when the name has none." + }, + "defaultMimeType": { + "type": "string", + "description": "FILE_DOWNLOAD, FILE_PREVIEW: MIME type to assume when none is known." + }, + "supplementalProcessName": { + "type": "string", + "description": "FILE_DOWNLOAD: process the server runs to produce the file (the client just downloads)." + }, + "supplementalCodeReference": { + "type": "object", + "description": "FILE_DOWNLOAD: code the server runs to produce the file (the client just downloads).", + "additionalProperties": true + }, + "downloadUrlDynamic": { + "type": "boolean", + "description": "FILE_DOWNLOAD: the download URL is per record - read it from the record displayValue `{fieldName}:downloadUrlDynamic`." + }, + "fileNameFormat": { + "type": "string", + "description": "FILE_DOWNLOAD: format (with %s placeholders) for the saved file name." + }, + "fileNameFormatFields": { + "type": "array", + "description": "FILE_DOWNLOAD: fields whose values fill fileNameFormat, in order.", + "items": { + "type": "string" + } + }, + "width": { + "type": "string", + "description": "SIZE: display width of the field - one of xsmall, small, medium, medlarge, large, xlarge (semantic widths; each client maps them to its own columns or characters). FILE_UPLOAD: width of the upload control.", + "enum": [ + "xsmall", + "small", + "medium", + "medlarge", + "large", + "xlarge", + "full", + "half" + ] + }, + "format": { + "type": "string", + "description": "FILE_UPLOAD: control style (dragAndDrop or button)." + }, + "valueIsUploadRef": { + "type": "boolean", + "description": "FILE_UPLOAD: upload the file with POST /uploads and send its ref as the field's value (null removes the file); the value read back is a URL to show. Since 1.8.0." + }, + "accept": { + "type": "string", + "description": "FILE_UPLOAD: accepted MIME types, comma-separated (e.g. image/png,image/jpeg). Since 1.8.0." + }, + "maxBytes": { + "type": "integer", + "description": "FILE_UPLOAD: largest accepted file in bytes. Since 1.8.0." + }, + "imageShape": { + "type": "string", + "description": "FILE_UPLOAD: the field is an image to crop and preview in this shape (square or circle; both crop square). Since 1.8.0.", + "enum": [ + "square", + "circle" + ] + }, + "languageMode": { + "type": "string", + "description": "CODE_EDITOR: language of the code (e.g. javascript, sql, json, velocity) - for highlighting; a client without an editor shows it monospaced." + }, + "staticText": { + "type": "string", + "description": "TOOLTIP: the tooltip text." + }, + "tooltipDynamic": { + "type": "boolean", + "description": "TOOLTIP: the text is per record - read it from the record displayValue `{fieldName}:tooltipDynamic`." + }, + "thumbnailUrlField": { + "type": "string", + "description": "FILE_PREVIEW: field holding a thumbnail image URL." + }, + "fullSizeUrlField": { + "type": "string", + "description": "FILE_PREVIEW: field holding the full-size file URL." + }, + "mimeTypeField": { + "type": "string", + "description": "FILE_PREVIEW: field holding the MIME type (decides image, video, PDF or download-only)." + }, + "altTextField": { + "type": "string", + "description": "FILE_PREVIEW: field holding alternative text." + }, + "captionField": { + "type": "string", + "description": "FILE_PREVIEW: field holding a caption." + }, + "widthField": { + "type": "string", + "description": "FILE_PREVIEW: field holding the pixel width." + }, + "heightField": { + "type": "string", + "description": "FILE_PREVIEW: field holding the pixel height." + }, + "sizeBytesField": { + "type": "string", + "description": "FILE_PREVIEW: field holding the size in bytes." + }, + "thumbnailMaxSize": { + "type": "integer", + "description": "FILE_PREVIEW: largest thumbnail edge in pixels." + }, + "previewable": { + "type": "boolean", + "description": "FILE_PREVIEW: whether the file may be previewed (false: download only)." + }, + "widgetName": { + "type": "string", + "description": "WIDGET: the widget that renders this field." + } + }, + "additionalProperties": {} + } + } + }, + "FieldMetaData": { + "type": "object", + "properties": { + "accessTier": { + "type": "string", + "description": "Effective field access: FULL, REVEALABLE, MASKED, or HIDDEN. Omitted means FULL. Restricted values are strings, regardless of field type.", + "enum": [ + "FULL", + "REVEALABLE", + "MASKED", + "HIDDEN" + ] + }, + "adornments": { + "type": "array", + "description": "Special UI dressings to add to the field.", + "items": { + "$ref": "#/components/schemas/FieldAdornment" + } + }, + "allowedFilterOperators": { + "type": "array", + "description": "Allowed filter operators when restricted: EQUALS and IN for REVEALABLE when exact match is enabled, otherwise empty. Omitted means unrestricted.", + "items": { + "type": "string" + } + }, + "behaviors": { + "type": "array", + "description": "Names of the field's behaviors that a frontend applies while editing, e.g., TO_UPPER_CASE, TO_LOWER_CASE or TRIM. Absent when the field has none.", + "items": { + "type": "string" + } + }, + "defaultValue": { + "type": "string", + "description": "Default value to use in this field." + }, + "displayFormat": { + "type": "string", + "description": "C-style format specifier for displaying values in this field." + }, + "gridColumns": { + "type": "number", + "description": "Width of this field in a 12-column record form or view grid (e.g., 12 for the full width, 6 for half). Absent when the frontend's default applies." + }, + "helpContents": { + "type": "array", + "description": "Help Contents for this field.", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + }, + "inlinePossibleValueSource": { + "type": "object", + "description": "Inline possible-value source for this field; enumValues supply choices without a separate lookup.", + "properties": { + "customCodeReference": { + "type": "object", + "properties": { + "codeType": { + "type": "string", + "enum": [ + "JAVA", + "JAVA_SCRIPT" + ] + }, + "inlineCode": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "enumValues": { + "type": "array" + }, + "helpContent": { + "type": "object" + }, + "idType": { + "type": "string", + "enum": [ + "STRING", + "INTEGER", + "LONG", + "DECIMAL", + "BOOLEAN", + "DATE", + "TIME", + "DATE_TIME", + "TEXT", + "HTML", + "PASSWORD", + "BLOB" + ] + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "orderByFields": { + "type": "array" + }, + "overrideIdField": { + "type": "string" + }, + "picker": { + "type": "object", + "properties": { + "detailFields": { + "type": "array" + }, + "filterFields": { + "type": "array" + }, + "pageSize": { + "type": "number" + }, + "previewField": { + "type": "string" + }, + "searchFields": { + "type": "array" + }, + "sorts": { + "type": "array" + }, + "subtitleFields": { + "type": "array" + }, + "thumbnailField": { + "type": "string" + }, + "uploadProcessName": { + "type": "string" + }, + "uploadResultIdField": { + "type": "string" + } + } + }, + "searchFields": { + "type": "array" + }, + "tableName": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "ENUM", + "TABLE", + "CUSTOM" + ] + }, + "valueFields": { + "type": "array" + }, + "valueFieldsIfNotFound": { + "type": "array" + }, + "valueFormat": { + "type": "string" + }, + "valueFormatIfNotFound": { + "type": "string" + } + } + }, + "isEditable": { + "type": "boolean", + "description": "Indicate if user may edit the value in this field.", + "nullable": true + }, + "isHeavy": { + "type": "boolean", + "description": "Indicator of 'heavy' fields, which are not loaded by default. e.g., some blobs or long-texts", + "nullable": true + }, + "isHidden": { + "type": "boolean", + "description": "Indicate if this field should be hidden from users", + "nullable": true + }, + "isRequired": { + "type": "boolean", + "description": "Indicate if a value in this field is required.", + "nullable": true + }, + "isSortable": { + "type": "boolean", + "description": "False for restricted fields; omitted means sortable.", + "nullable": true + }, + "label": { + "type": "string", + "description": "User-facing name for this field" + }, + "maxLength": { + "type": "number", + "description": "For String fields, the max length the field supports." + }, + "maxValue": { + "type": "string", + "description": "For number fields, the largest value the field accepts (inclusive). Absent when there is no such limit." + }, + "minValue": { + "type": "string", + "description": "For number fields, the smallest value the field accepts (inclusive). Absent when there is no such limit." + }, + "name": { + "type": "string", + "description": "Unique name for this field within its container (table or process)" + }, + "picker": { + "type": "object", + "description": "When this field's possible value source declares a record picker (for sources over large tables), its configuration: thumbnail, preview, subtitle and detail fields, filter fields, search fields, sorts and page size. Frontends offer a searchable, paged picker dialog.", + "properties": { + "detailFields": { + "type": "array" + }, + "filterFields": { + "type": "array" + }, + "pageSize": { + "type": "number" + }, + "previewField": { + "type": "string" + }, + "searchFields": { + "type": "array" + }, + "sorts": { + "type": "array" + }, + "subtitleFields": { + "type": "array" + }, + "thumbnailField": { + "type": "string" + }, + "uploadProcessName": { + "type": "string" + }, + "uploadResultIdField": { + "type": "string" + } + } + }, + "pickerTableName": { + "type": "string", + "description": "When this field has a picker, the table its possible value source reads, whose metadata describes the picker's fields." + }, + "possibleValueSourceDependencyBehavior": { + "type": "string", + "description": "DISABLE_UNTIL_SET disables a contingent field until its dependencies are set (default). SHOW_ALL_UNTIL_SET keeps it enabled and omits criteria with missing inputs in form searches. Absent for non-contingent fields.", + "enum": [ + "DISABLE_UNTIL_SET", + "SHOW_ALL_UNTIL_SET" + ] + }, + "possibleValueSourceDependsOn": { + "type": "array", + "description": "Names of fields controlling this field's choices, including explicit and filter dependencies. Absent for non-contingent fields.", + "items": { + "type": "string" + } + }, + "possibleValueSourceName": { + "type": "string", + "description": "If this field's values should come from a possible value source, then that PVS is named here." + }, + "supplementalMetaData": { + "type": "object", + "description": "Additional frontend-visible metadata for this field, keyed by supplemental type." + }, + "type": { + "type": "string", + "description": "Data-type for this field" + }, + "validation": { + "description": "The field's validation rules, as the server enforces them on insert and update (required, maxLength and tooLongBehavior, min/max value, pattern). Absent when the field has none. Since 1.6.0.", + "$ref": "#/components/schemas/FieldValidationV1" + } + } + }, + "FieldValidationV1": { + "type": "object", + "properties": { + "maxInclusive": { + "type": "boolean", + "description": "Whether maxValue itself is accepted (false: the value must be less).", + "nullable": true + }, + "maxLength": { + "type": "number", + "description": "For string fields, the most characters the field stores. What happens to a longer value is tooLongBehavior." + }, + "maxValue": { + "type": "string", + "description": "For number fields, the largest value accepted (plain digits, exact). See maxInclusive." + }, + "minInclusive": { + "type": "boolean", + "description": "Whether minValue itself is accepted (false: the value must be greater).", + "nullable": true + }, + "minValue": { + "type": "string", + "description": "For number fields, the smallest value accepted (plain digits, exact). See minInclusive." + }, + "pattern": { + "type": "string", + "description": "A regular expression a non-empty value must match as a whole (written to mean the same in Java and ECMAScript)." + }, + "patternMessage": { + "type": "string", + "description": "The message the server gives for a value that does not match pattern." + }, + "required": { + "type": "boolean", + "description": "True when a value is required.", + "nullable": true + }, + "tooLongBehavior": { + "type": "string", + "description": "With maxLength: ERROR (a longer value is refused), TRUNCATE or TRUNCATE_ELLIPSIS (it is trimmed on save), PASS_THROUGH (neither)." + } + } + }, + "FilterCriteria": { + "properties": { + "fieldName": { + "description": "Field name that this criteria applies to", + "type": "string" + }, + "operator": { + "description": "Logical operator that applies to this criteria", + "enum": [ + "EQUALS", + "NOT_EQUALS", + "NOT_EQUALS_OR_IS_NULL", + "IN", + "NOT_IN", + "IS_NULL_OR_IN", + "LIKE", + "NOT_LIKE", + "STARTS_WITH", + "ENDS_WITH", + "CONTAINS", + "CONTAINS_ALL", + "NOT_STARTS_WITH", + "NOT_ENDS_WITH", + "NOT_CONTAINS", + "LESS_THAN", + "LESS_THAN_OR_EQUALS", + "GREATER_THAN", + "GREATER_THAN_OR_EQUALS", + "IS_BLANK", + "IS_NOT_BLANK", + "BETWEEN", + "NOT_BETWEEN", + "TRUE", + "FALSE" + ], + "type": "string" + }, + "values": { + "description": "Values to apply via the operator to the field", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "FormAdjusterOutputV1": { + "type": "object", + "description": "Changes a form adjuster asks the form to apply. Absent or null properties mean no change.", + "properties": { + "updatedFieldMetaData": { + "type": "object", + "description": "Replacement definitions for fields, by field name.", + "additionalProperties": { + "$ref": "#/components/schemas/FieldMetaData" + } + }, + "updatedFieldValues": { + "type": "object", + "description": "New values for fields, by field name.", + "additionalProperties": true + }, + "updatedFieldDisplayValues": { + "type": "object", + "description": "Display values for possible-value fields whose values changed, by field name.", + "additionalProperties": { + "type": "string" + } + }, + "fieldsToClear": { + "type": "array", + "description": "Fields whose values should be cleared.", + "items": { + "type": "string" + } + }, + "updatedSectionMetaData": { + "type": "object", + "description": "Replacement definitions for form sections, by section name.", + "additionalProperties": { + "$ref": "#/components/schemas/TableSection" + } + }, + "isFormDisabled": { + "type": "boolean", + "description": "Whether the form should be disabled." + }, + "formDisabledMessage": { + "type": "string", + "description": "Why the form is disabled." + } + } + }, + "FrontendComponent": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "The type of this component. e.g., what kind of UI element(s) should be presented to the user.", + "enum": [ + "HELP_TEXT", + "BULK_EDIT_FORM", + "BULK_LOAD_FILE_MAPPING_FORM", + "BULK_LOAD_VALUE_MAPPING_FORM", + "BULK_LOAD_PROFILE_FORM", + "VALIDATION_REVIEW_SCREEN", + "EDIT_FORM", + "VIEW_FORM", + "DOWNLOAD_FORM", + "RECORD_LIST", + "PROCESS_SUMMARY_RESULTS", + "GOOGLE_DRIVE_SELECT_FOLDER", + "WIDGET", + "HTML" + ] + }, + "values": { + "type": "object", + "description": "Name-value pairs specific to the type of component.", + "$ref": "#/components/schemas/FrontendComponentValues" + } + } + }, + "FrontendComponentValues": { + "type": "object", + "description": "These are the known values that can appear in the values map under a FrontendComponent, to control\nhow that component should be presented to the user.\n\nAdditional application-defined properties may appear as well. BULK_EDIT_FORM, BULK_LOAD_FILE_MAPPING_FORM,\nBULK_LOAD_VALUE_MAPPING_FORM, BULK_LOAD_PROFILE_FORM, VALIDATION_REVIEW_SCREEN, VIEW_FORM, DOWNLOAD_FORM,\nRECORD_LIST, PROCESS_SUMMARY_RESULTS and GOOGLE_DRIVE_SELECT_FOLDER have no fixed component-local keys\nsupplied by the core producers; they consume process values and frontend-step metadata.\n\nIn addition, components are expected to use values from an active process's `values` map (e.g., as included in\na `ProcessStepComplete` object), with the following contract between component-types and expected values:\n\n- For component type=`HTML`, there will be a process value with key=`${stepName}.html` (e.g., `resultScreen.html`),\nwhose value is the HTML to display on that screen.\n- For component type=`HELP_TEXT`: There will be a process value with key=`text`, whose value is the text to display on that screen.\nThere may also be a process value with key=`previewText`, which, if present, can be shown before the full text is shown,\ne.g., with a toggle control to hide/show the `text` value.\n", + "properties": { + "blocks": { + "type": "array", + "description": "Components of type=`WIDGET`, which are set as `isAdHocWidget=true`, should include a list of WidgetBlocks in this value.", + "items": { + "$ref": "#/components/schemas/WidgetBlock" + } + }, + "includeFieldNames": { + "type": "array", + "description": "Components of type=`EDIT_FORM` can specify a subset of field names to include. This can be used to break a form up into\nsections, by including multiple EDIT_FORM components, with different lists of `includeFieldNames`.\n", + "items": { + "type": "string" + } + }, + "isAdHocWidget": { + "type": "boolean", + "description": "Components of type=`WIDGET`, which do not reference a widget defined in the QQQ Instance, but instead,\nare defined as a list of blocks within a frontend step component, will have a this value set to true.", + "nullable": true + }, + "previewText": { + "type": "string", + "description": "HELP_TEXT: short text shown before expanding the full text." + }, + "sectionLabel": { + "type": "string", + "description": "Components of type=`EDIT_FORM` can specify a user-facing text label to show on screen.\n" + }, + "text": { + "type": "string", + "description": "HELP_TEXT: text shown by the component." + }, + "widgetName": { + "type": "string", + "description": "Components of type=`WIDGET`, which should render a widget defined in the QQQ instance, this value specifies\nthe name of that widget. Contrast with ad-hoc widgets.\n" + } + } + }, + "FrontendStep": { + "type": "object", + "properties": { + "backStepName": { + "type": "string", + "description": "Name of the step a user can go back to from this step (step with isStepBack=true), when there is one." + }, + "components": { + "type": "array", + "description": "The components that make up this screen", + "items": { + "$ref": "#/components/schemas/FrontendComponent" + } + }, + "formFields": { + "type": "array", + "description": "Fields used as form fields (inputs) on this step/screen", + "items": { + "$ref": "#/components/schemas/FieldMetaData" + } + }, + "format": { + "type": "string", + "description": "An optional indicator of the screen format preferred by the application to be used for this screen. Different frontends may support different formats, and implement them differently." + }, + "helpContents": { + "type": "array", + "description": "Help content shown on the step/screen.", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + }, + "label": { + "type": "string", + "description": "The user-facing name for this step" + }, + "name": { + "type": "string", + "description": "The unique name for this step within its process" + }, + "recordListFields": { + "type": "array", + "description": "Fields used in record-lists shown on the step/screen.", + "items": { + "$ref": "#/components/schemas/FieldMetaData" + } + }, + "viewFields": { + "type": "array", + "description": "Fields used as view-only fields on this step/screen", + "items": { + "$ref": "#/components/schemas/FieldMetaData" + } + } + } + }, + "HelpContentV1": { + "type": "object", + "properties": { + "content": { + "type": "string", + "description": "Long help in the declared format." + }, + "contentAsHtml": { + "type": "string", + "description": "Rendered Markdown (raw HTML escaped, unsafe links removed). Explicit HTML is unchanged and clients must sanitize it." + }, + "contentAsText": { + "type": "string", + "description": "Plain-text help, preserving link text and line breaks." + }, + "format": { + "type": "string", + "description": "Format of the long help.", + "enum": [ + "TEXT", + "HTML", + "MARKDOWN" + ] + }, + "roles": { + "type": "array", + "description": "Screen roles covered by this entry.", + "items": { + "type": "string" + } + }, + "summary": { + "type": "string", + "description": "Optional short plain-text tooltip." + } + } + }, + "HelpCoverageEntryV1": { + "type": "object", + "properties": { + "hasContent": { + "type": "boolean", + "description": "Whether visible help has long content.", + "nullable": true + }, + "hasSummary": { + "type": "boolean", + "description": "Whether visible help has an explicit summary.", + "nullable": true + }, + "hidden": { + "type": "boolean", + "description": "Whether the target is hidden in metadata.", + "nullable": true + }, + "key": { + "type": "string", + "description": "Canonical helpContent address." + }, + "kind": { + "type": "string", + "description": "Help target kind." + }, + "label": { + "type": "string", + "description": "User-facing target label." + }, + "parentKey": { + "type": "string", + "description": "Canonical parent address." + }, + "roles": { + "type": "array", + "description": "Screen roles covered by this entry.", + "items": { + "type": "string" + } + } + } + }, + "HelpCoverageResponseV1": { + "type": "object", + "properties": { + "entries": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HelpCoverageEntryV1" + } + }, + "totals": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HelpCoverageTotalV1" + } + } + } + }, + "HelpCoverageTotalV1": { + "type": "object", + "properties": { + "kind": { + "type": "string", + "description": "Help target kind." + }, + "total": { + "type": "number", + "description": "Number of targets in the selected kind and parent scope." + }, + "withHelp": { + "type": "number", + "description": "Targets with a visible summary or long content." + } + } + }, + "HelpSearchResponseV1": { + "type": "object", + "properties": { + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HelpSearchResultV1" + } + } + } + }, + "HelpSearchResultV1": { + "type": "object", + "properties": { + "contentAsHtml": { + "type": "string", + "description": "Rendered Markdown (raw HTML escaped, unsafe links removed). Explicit HTML is unchanged and clients must sanitize it." + }, + "contentAsText": { + "type": "string", + "description": "Plain-text help, preserving link text and line breaks." + }, + "href": { + "type": "string", + "description": "Application-relative navigation link, when available." + }, + "key": { + "type": "string", + "description": "Canonical helpContent address." + }, + "kind": { + "type": "string", + "description": "Help target kind." + }, + "label": { + "type": "string", + "description": "User-facing target label." + }, + "name": { + "type": "string", + "description": "Target metadata name." + }, + "process": { + "type": "string", + "description": "Related process name, when applicable." + }, + "summary": { + "type": "string", + "description": "Optional short plain-text tooltip." + }, + "table": { + "type": "string", + "description": "Related table name, when applicable." + }, + "text": { + "type": "string", + "description": "Plain-text help excerpt, at most 600 characters." + } + } + }, + "Icon": { + "type": "object", + "properties": { + "color": { + "type": "string", + "description": "A color code to use for displaying the icon" + }, + "name": { + "type": "string", + "description": "Material UI icon name (web); prefer semanticName" + }, + "path": { + "type": "string", + "description": "A path to an image file that can be requested from the server, to serve as the icon image instead of a material UI icon." + }, + "semanticName": { + "type": "string", + "description": "Client-neutral kebab-case icon token; null when unmapped." + } + } + }, + "JobActionResponseV1": { + "type": "object", + "properties": { + "jobId": { + "type": "number" + } + } + }, + "JobDetailV1": { + "type": "object", + "properties": { + "actions": { + "type": "array", + "items": { + "type": "string" + } + }, + "bytesDone": { + "type": "number" + }, + "bytesTotal": { + "type": "number" + }, + "chunksDone": { + "type": "number" + }, + "chunksTotal": { + "type": "number" + }, + "currentPhase": { + "type": "string" + }, + "etaSeconds": { + "type": "number" + }, + "finishedAt": { + "type": "string" + }, + "jobId": { + "type": "number" + }, + "label": { + "type": "string" + }, + "logSeq": { + "type": "number" + }, + "message": { + "type": "string" + }, + "percent": { + "type": "number" + }, + "processName": { + "type": "string" + }, + "progress": { + "type": "object", + "properties": { + "bytesDone": { + "type": "number" + }, + "bytesTotal": { + "type": "number" + }, + "currentPhase": { + "type": "string" + }, + "done": { + "type": "number" + }, + "etaSeconds": { + "type": "number" + }, + "message": { + "type": "string" + }, + "percent": { + "type": "number" + }, + "phases": { + "type": "array", + "items": { + "$ref": "#/components/schemas/JobPhaseV1" + } + }, + "total": { + "type": "number" + }, + "unitLabel": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "queuedAt": { + "type": "string" + }, + "rowsDone": { + "type": "number" + }, + "rowsFailed": { + "type": "number" + }, + "rowsTotal": { + "type": "number" + }, + "sourceType": { + "type": "string" + }, + "startedAt": { + "type": "string" + }, + "status": { + "type": "string" + }, + "summary": { + "type": "object" + }, + "userId": { + "type": "string" + } + } + }, + "JobListResponseV1": { + "type": "object", + "properties": { + "activeCount": { + "type": "number" + }, + "generatedAt": { + "type": "string" + }, + "jobs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/JobSummaryV1" + } + } + } + }, + "JobLogLineV1": { + "type": "object", + "properties": { + "attempt": { + "type": "number" + }, + "chunkId": { + "type": "number" + }, + "id": { + "type": "number" + }, + "jobId": { + "type": "number" + }, + "level": { + "type": "string" + }, + "loggedAt": { + "type": "string" + }, + "message": { + "type": "string" + }, + "phase": { + "type": "string" + } + } + }, + "JobPhaseV1": { + "type": "object", + "properties": { + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "status": { + "type": "string" + }, + "weight": { + "type": "number" + } + } + }, + "JobProgressPollV1": { + "type": "object", + "properties": { + "job": { + "type": "object", + "properties": { + "bytesDone": { + "type": "number" + }, + "bytesTotal": { + "type": "number" + }, + "chunksDone": { + "type": "number" + }, + "chunksTotal": { + "type": "number" + }, + "currentPhase": { + "type": "string" + }, + "etaSeconds": { + "type": "number" + }, + "finishedAt": { + "type": "string" + }, + "jobId": { + "type": "number" + }, + "label": { + "type": "string" + }, + "logSeq": { + "type": "number" + }, + "message": { + "type": "string" + }, + "percent": { + "type": "number" + }, + "processName": { + "type": "string" + }, + "queuedAt": { + "type": "string" + }, + "rowsDone": { + "type": "number" + }, + "rowsFailed": { + "type": "number" + }, + "rowsTotal": { + "type": "number" + }, + "sourceType": { + "type": "string" + }, + "startedAt": { + "type": "string" + }, + "status": { + "type": "string" + }, + "userId": { + "type": "string" + } + } + }, + "log": { + "type": "array", + "items": { + "$ref": "#/components/schemas/JobLogLineV1" + } + }, + "logDropped": { + "type": "number" + }, + "nextAfterLogId": { + "type": "number" + }, + "progress": { + "type": "object", + "properties": { + "bytesDone": { + "type": "number" + }, + "bytesTotal": { + "type": "number" + }, + "currentPhase": { + "type": "string" + }, + "done": { + "type": "number" + }, + "etaSeconds": { + "type": "number" + }, + "message": { + "type": "string" + }, + "percent": { + "type": "number" + }, + "phases": { + "type": "array", + "items": { + "$ref": "#/components/schemas/JobPhaseV1" + } + }, + "total": { + "type": "number" + }, + "unitLabel": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "terminal": { + "type": "boolean", + "nullable": true + } + } + }, + "JobProgressV1": { + "type": "object", + "properties": { + "bytesDone": { + "type": "number" + }, + "bytesTotal": { + "type": "number" + }, + "currentPhase": { + "type": "string" + }, + "done": { + "type": "number" + }, + "etaSeconds": { + "type": "number" + }, + "message": { + "type": "string" + }, + "percent": { + "type": "number" + }, + "phases": { + "type": "array", + "items": { + "$ref": "#/components/schemas/JobPhaseV1" + } + }, + "total": { + "type": "number" + }, + "unitLabel": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "JobSummaryV1": { + "type": "object", + "properties": { + "bytesDone": { + "type": "number" + }, + "bytesTotal": { + "type": "number" + }, + "chunksDone": { + "type": "number" + }, + "chunksTotal": { + "type": "number" + }, + "currentPhase": { + "type": "string" + }, + "etaSeconds": { + "type": "number" + }, + "finishedAt": { + "type": "string" + }, + "jobId": { + "type": "number" + }, + "label": { + "type": "string" + }, + "logSeq": { + "type": "number" + }, + "message": { + "type": "string" + }, + "percent": { + "type": "number" + }, + "processName": { + "type": "string" + }, + "queuedAt": { + "type": "string" + }, + "rowsDone": { + "type": "number" + }, + "rowsFailed": { + "type": "number" + }, + "rowsTotal": { + "type": "number" + }, + "sourceType": { + "type": "string" + }, + "startedAt": { + "type": "string" + }, + "status": { + "type": "string" + }, + "userId": { + "type": "string" + } + } + }, + "JobTrackRequestV1": { + "type": "object", + "properties": { + "jobUUID": { + "type": "string" + }, + "processName": { + "type": "string" + }, + "processUUID": { + "type": "string" + } + } + }, + "LogoutResponseV1": { + "type": "object" + }, + "ManageSessionResponseV1": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "description": "Unique identifier of the session. Required to be returned on subsequent requests in the sessionUUID Cookie, to prove authentication. Not included when the cookie is HttpOnly or the session was resumed from that cookie." + }, + "values": { + "type": "object", + "description": "Optional object with application-defined values. `user` describes the signed-in user: `name`, `email` or `username` (by authentication module), and, when the application installs user profiles (since 1.8.0), `displayName` (the name the user chose; prefer it to `name`) and `avatarUrl` (relative URL of GET /avatars/{avatarId} with its version; add `&size=32|64|128|256`). No `avatarUrl` means draw initials.", + "additionalProperties": true + } + } + }, + "MaterialDashboardInstanceSettings": { + "type": "object", + "properties": { + "processNamesToAddToAllQueryAndViewScreens": { + "type": "array", + "description": "Names of processes to offer on the query and record-view screens of every table, in their configured order. Only processes that the user may see (i.e., that are in the meta-data's `processes` map) are listed, so the list may be empty.", + "items": { + "type": "string" + } + }, + "recordViewActionsPlacement": { + "type": "string", + "description": "Where the record view puts its actions: IN_IDENTITY_SECTION or INLINE_WITH_PAGE_TITLE. When set, this overrides each table's placement." + }, + "weekdayCriteriaSettings": { + "description": "Weekday criteria settings for the query screens (day is any of, day is none of). Omitted when the material dashboard meta-data does not define them.", + "$ref": "#/components/schemas/MaterialDashboardWeekdayCriteriaSettings" + } + } + }, + "MaterialDashboardWeekdayCriteriaSettings": { + "type": "object", + "properties": { + "dateTimeFieldFunctionArguments": { + "type": "object", + "description": "Arguments for the WeekdayOfDateTime field function that a frontend sends with weekday criteria on date-time fields (for example timeZoneId or useSessionZoneId).", + "$ref": "#/components/schemas/WeekdayCriteriaArguments" + }, + "enabled": { + "type": "boolean", + "description": "Whether query screens offer the weekday criteria (day is any of, day is none of) on date and date-time fields.", + "nullable": true + } + } + }, + "MetaDataResponseV1": { + "type": "object", + "properties": { + "appTree": { + "type": "array", + "description": "Tree of apps within the QQQ Instance, sorted and organized hierarchically, for presentation to a user.", + "items": { + "$ref": "#/components/schemas/AppTreeNode" + } + }, + "apps": { + "type": "object", + "description": "Map of all apps within the QQQ Instance (that the user has permission to see that they exist).", + "additionalProperties": { + "$ref": "#/components/schemas/AppMetaData" + } + }, + "branding": { + "type": "object", + "description": "Application identity (names, logo, icon, accent colors and banners), when the instance defines it.", + "properties": { + "accentColor": { + "type": "string", + "description": "Primary accent color, as a CSS color value." + }, + "accentColorLight": { + "type": "string", + "description": "Light variant of the accent color, as a CSS color value." + }, + "appName": { + "type": "string", + "description": "Name of this application, for display to users." + }, + "banners": { + "type": "object", + "description": "Banners to display, keyed by the slot where each is shown.", + "additionalProperties": { + "$ref": "#/components/schemas/BrandingBanner" + } + }, + "companyName": { + "type": "string", + "description": "Name of the company that operates this application." + }, + "companyUrl": { + "type": "string", + "description": "URL for the company's web site." + }, + "icon": { + "type": "string", + "description": "Path or URL of the application's small icon image." + }, + "logo": { + "type": "string", + "description": "Path or URL of the application's logo image." + } + } + }, + "environmentValues": { + "type": "object", + "description": "Environment values a frontend may use: Google Picker public browser settings GOOGLE_APP_CLIENT_ID and GOOGLE_APP_API_KEY, and the analytics settings (ANALYTICS_PROVIDERS, ANALYTICS_PLUGIN_SCRIPTS, ANALYTICS_PLUGIN_SCRIPT_URLS, GOOGLE_ANALYTICS_ENABLED, GOOGLE_ANALYTICS_TRACKING_ID, POSTHOG_ENABLED, POSTHOG_API_KEY, POSTHOG_PROJECT_API_KEY, POSTHOG_HOST, and any other ANALYTICS_* value), from the instance's QQQ_ENV_* environment. An explicit allow-list - never the whole environment. Omitted when none are set.", + "additionalProperties": { + "type": "string" + } + }, + "helpContents": { + "type": "object", + "description": "Instance-level help content, by slot name (for example the query screen's bulkAddFilterValues and bulkAddFilterValuesPossibleValueSource slots). Omitted when the instance defines none.", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + } + }, + "homeAppName": { + "type": "string", + "description": "Name of the app whose dashboard a frontend shows as the instance's home page (for example at /app/), when the instance designates one and the user may access that app. Omitted otherwise, in which case the frontend uses its own default home page." + }, + "metaDataGeneration": { + "type": "number" + }, + "processes": { + "type": "object", + "description": "Map of all processes within the QQQ Instance (that the user has permission to see that they exist).", + "additionalProperties": { + "$ref": "#/components/schemas/ProcessMetaDataLight" + } + }, + "reports": { + "type": "object", + "description": "Map of all reports within the QQQ Instance (that the user has permission to see that they exist).", + "additionalProperties": { + "type": "object", + "properties": { + "hasPermission": { + "type": "boolean", + "description": "Whether the user may run the report." + }, + "helpContents": { + "type": "object", + "description": "Help entries by slot, filtered for the current session.", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + } + }, + "iconName": { + "type": "string", + "description": "Material UI icon name (web); prefer iconSemanticName" + }, + "iconSemanticName": { + "type": "string", + "description": "Client-neutral kebab-case icon token; null when unmapped." + }, + "label": { + "type": "string", + "description": "User-facing name for this report." + }, + "name": { + "type": "string", + "description": "Unique name for this report within the QQQ Instance." + }, + "processName": { + "type": "string", + "description": "Process that runs this report, when it has one; otherwise it runs from GET /reports/{reportName}." + } + } + } + }, + "supplementalInstanceMetaData": { + "type": "object", + "description": "Settings from supplemental modules that a frontend may use (an explicit allow-list - not the supplemental meta-data objects themselves). Omitted when the instance defines none of them.", + "properties": { + "assistant": { + "type": "object", + "description": "Present (an object) when the instance has the assistant QBit's `assistant` supplemental meta-data - that is, when the assistant is installed and enabled, so a frontend may probe its routes. Always has `available: true`, plus the strings, numbers and booleans the QBit publishes for frontends.", + "additionalProperties": true + }, + "materialDashboard": { + "type": "object", + "description": "Use uiSettings; kept for Next UI until it migrates", + "properties": { + "processNamesToAddToAllQueryAndViewScreens": { + "type": "array", + "description": "Names of processes to offer on the query and record-view screens of every table, in their configured order. Only processes that the user may see (i.e., that are in the meta-data's `processes` map) are listed, so the list may be empty.", + "items": { + "type": "string" + } + }, + "recordViewActionsPlacement": { + "type": "string", + "description": "Where the record view puts its actions: IN_IDENTITY_SECTION or INLINE_WITH_PAGE_TITLE. When set, this overrides each table's placement." + }, + "weekdayCriteriaSettings": { + "type": "object", + "description": "Weekday criteria settings for the query screens (day is any of, day is none of). Omitted when the material dashboard meta-data does not define them.", + "properties": { + "dateTimeFieldFunctionArguments": { + "type": "object", + "description": "Arguments for the WeekdayOfDateTime field function that a frontend sends with weekday criteria on date-time fields (for example timeZoneId or useSessionZoneId).", + "$ref": "#/components/schemas/WeekdayCriteriaArguments" + }, + "enabled": { + "type": "boolean", + "description": "Whether query screens offer the weekday criteria (day is any of, day is none of) on date and date-time fields.", + "nullable": true + } + } + } + }, + "deprecated": true + }, + "materialDashboardTheme": { + "type": "object", + "description": "Use uiSettings; kept for Next UI until it migrates. The application theme from the instance's MaterialDashboardThemeMetaData supplemental meta-data, when the instance defines it. Keys are MaterialDashboardThemeMetaData property names (for example primaryColor, fontFamily, typographyH1FontSize, borderRadiusGlobal, density, customCss, brandedHeaderEnabled, sidebarBackgroundColor, tableHeaderBackgroundColor); values are strings, numbers or booleans. An explicit allow-list of the theme's visual properties; properties without a value are omitted.", + "additionalProperties": true, + "deprecated": true + }, + "uiSettings": { + "type": "object", + "description": "Client-neutral process, query, record-view and theme settings.", + "properties": { + "processNamesToAddToAllQueryAndViewScreens": { + "type": "array", + "description": "Visible processes offered on every query and record-view screen.", + "items": { + "type": "string" + } + }, + "recordViewActionsPlacement": { + "type": "string", + "description": "Placement of record-view actions." + }, + "theme": { + "type": "object", + "description": "Configured colors and font families; no web layout or CSS settings.", + "additionalProperties": { + "type": "string" + } + }, + "weekdayCriteriaSettings": { + "type": "object", + "description": "Weekday query criteria configuration.", + "properties": { + "dateTimeFieldFunctionArguments": { + "type": "object", + "description": "Arguments for the WeekdayOfDateTime field function that a frontend sends with weekday criteria on date-time fields (for example timeZoneId or useSessionZoneId).", + "$ref": "#/components/schemas/WeekdayCriteriaArguments" + }, + "enabled": { + "type": "boolean", + "description": "Whether query screens offer the weekday criteria (day is any of, day is none of) on date and date-time fields.", + "nullable": true + } + } + } + } + } + } + }, + "tables": { + "type": "object", + "description": "Map of all tables within the QQQ Instance (that the user has permission to see that they exist).", + "additionalProperties": { + "$ref": "#/components/schemas/TableMetaDataLight" + } + }, + "widgets": { + "type": "object", + "description": "Map of all widgets within the QQQ Instance (that the user has permission to see that they exist).", + "additionalProperties": { + "type": "object", + "properties": { + "defaultValues": { + "type": "object", + "description": "Frontend widget defaults, including explicit association bindings", + "additionalProperties": true + }, + "dropdowns": { + "type": "array", + "description": "Dropdowns the widget offers to filter its data." + }, + "footerHTML": { + "type": "string", + "description": "HTML shown below the widget." + }, + "footerText": { + "type": "string", + "description": "Plain-text footer, preserving link text and line breaks." + }, + "gridColumns": { + "type": "number", + "description": "Number of grid columns (of 12) the widget spans." + }, + "hasPermission": { + "type": "boolean", + "description": "Whether the user may render the widget." + }, + "helpContent": { + "type": "object", + "description": "Help content by slot.", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + } + }, + "icon": { + "type": "string", + "description": "Name of the widget's icon." + }, + "icons": { + "type": "object", + "description": "Icons by role (for example the widget header icon).", + "additionalProperties": true + }, + "isCard": { + "type": "boolean", + "description": "Whether the widget is drawn as a card." + }, + "label": { + "type": "string", + "description": "User-facing name for this widget" + }, + "minHeight": { + "type": "string", + "description": "Minimum height of the widget (a CSS length)." + }, + "name": { + "type": "string", + "description": "Unique name for this widget within the QQQ Instance" + }, + "showExportButton": { + "type": "boolean", + "description": "Whether the widget offers an export button." + }, + "showReloadButton": { + "type": "boolean", + "description": "Whether the widget offers a reload button." + }, + "storeDropdownSelections": { + "type": "boolean", + "description": "Whether dropdown selections are remembered for the user." + }, + "tooltip": { + "type": "string", + "description": "Tooltip text for the widget." + }, + "type": { + "type": "string", + "description": "The type of this widget." + } + } + } + } + } + }, + "OrderBy": { + "properties": { + "fieldName": { + "description": "Field name that this order-by applies to", + "type": "string" + }, + "isAscending": { + "description": "Whether this order-by is ascending or descending", + "nullable": true, + "type": "boolean" + } + }, + "type": "object" + }, + "OutputRecord": { + "type": "object", + "properties": { + "associatedRecords": { + "type": "object", + "description": "Records associated with this record, keyed by association name. Each value is a list of records with the same shape as this one. Only present when associations were requested or written.", + "additionalProperties": { + "type": "array" + } + }, + "displayValues": { + "type": "object", + "description": "Formatted string versions of the values that make up the record. Keys are Strings, which match the table's field names. Values are all Strings." + }, + "errors": { + "type": "array", + "description": "Messages for errors on this record (for example on an associated record that could not be written). Omitted when there are none.", + "items": { + "type": "string" + } + }, + "recordLabel": { + "type": "string", + "description": "Label to identify the record to a user." + }, + "tableName": { + "type": "string", + "description": "Name of the table that the record is from." + }, + "values": { + "type": "object", + "description": "Raw values that make up the record. Keys are Strings, which match the table's field names. Values can be any type, as per the table's fields. Single-record responses (get, insert, update) include fields whose value is null; query results omit them." + }, + "warnings": { + "type": "array", + "description": "Messages for warnings on this record. Omitted when there are none.", + "items": { + "type": "string" + } + } + } + }, + "PossibleValueOption": { + "type": "object", + "properties": { + "displayValues": { + "type": "object", + "description": "For a picker request: formatted or translated display values, where they differ from the raw values" + }, + "id": { + "type": "object", + "description": "Unique identifier for this possible value option" + }, + "label": { + "type": "string", + "description": "Human-readable label for this possible value option" + }, + "values": { + "type": "object", + "description": "For a picker request: the option's picker display values (thumbnail, preview, subtitle and detail fields), raw" + } + } + }, + "PossibleValuesResponseV1": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean", + "description": "For a picker request: whether another page of options follows (the picker never counts)", + "nullable": true + }, + "options": { + "type": "array", + "description": "List of possible value options matching the search request", + "items": { + "$ref": "#/components/schemas/PossibleValueOption" + } + } + } + }, + "PreferenceActionRequestV1": { + "type": "object", + "description": "Only rowKey and values are accepted. Identity always comes from the authenticated session.", + "properties": { + "rowKey": { + "type": "string", + "description": "Required for ROW actions: a key loaded for this user with the action allowed. Forbidden for SECTION and LIST actions." + }, + "values": { + "type": "object", + "description": "Action input fields. Validated and coerced like PATCH fields; unknown fields are rejected.", + "additionalProperties": {} + } + }, + "additionalProperties": false + }, + "PreferenceActionResponseV1": { + "type": "object", + "description": "Action result and reloaded section. Secrets are shown once and must not be stored by clients. Response uses Cache-Control: no-store.", + "properties": { + "section": { + "$ref": "#/components/schemas/PreferenceSectionV1" + }, + "message": { + "type": "string", + "description": "User-facing outcome message." + }, + "secrets": { + "type": "array", + "description": "One-time secrets for immediate display; clients must not store them.", + "items": { + "$ref": "#/components/schemas/PreferenceSecretV1" + } + }, + "focusRowKey": { + "type": "string", + "description": "Optional row key to focus after reloading the section." + } + } + }, + "PreferenceActionV1": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Stable action name used in URLs." + }, + "label": { + "type": "string", + "description": "Human-readable action label." + }, + "icon": { + "$ref": "#/components/schemas/Icon" + }, + "description": { + "type": "string", + "description": "Explanation for clients to display." + }, + "scope": { + "type": "string", + "description": "Where to display this action. ROW actions require a loaded row key.", + "enum": [ + "SECTION", + "LIST", + "ROW" + ] + }, + "listName": { + "type": "string", + "description": "List targeted by LIST or ROW actions; null for SECTION.", + "nullable": true + }, + "confirmationText": { + "type": "string", + "description": "When set, clients must confirm with this text before running the action.", + "nullable": true + }, + "isDestructive": { + "type": "boolean", + "description": "Whether clients should present this as a destructive action." + }, + "inputFields": { + "type": "array", + "description": "Action inputs, using preference field validation and coercion.", + "items": { + "$ref": "#/components/schemas/FieldMetaData" + } + }, + "order": { + "type": "integer", + "description": "Display order, ascending then label; defaults to 100." + } + } + }, + "PreferenceListV1": { + "type": "object", + "description": "A list of fixed preference rows, rendered with the same typed field editors as scalar preferences.", + "properties": { + "name": { + "type": "string", + "description": "List name used in PATCH lists." + }, + "label": { + "type": "string", + "description": "Human-readable list title." + }, + "description": { + "type": "string", + "description": "Explanation of this list." + }, + "rowLabel": { + "type": "string", + "description": "Label for one row, such as Category." + }, + "fields": { + "type": "array", + "description": "Editable columns and their validation rules.", + "items": { + "$ref": "#/components/schemas/FieldMetaData" + } + }, + "rows": { + "type": "array", + "description": "Fixed rows available to this user.", + "items": { + "$ref": "#/components/schemas/PreferenceRowV1" + } + } + } + }, + "PreferenceRowV1": { + "type": "object", + "description": "A provider-owned row. Clients change row membership only through registered actions.", + "properties": { + "actionNames": { + "type": "array", + "description": "Null allows every ROW action of this list; empty allows none; otherwise only the named actions are allowed.", + "items": { + "type": "string" + }, + "nullable": true + }, + "key": { + "type": "string", + "description": "Stable provider row key to send when patching." + }, + "label": { + "type": "string", + "description": "Human-readable row label." + }, + "description": { + "type": "string", + "description": "Explanation of this row." + }, + "values": { + "type": "object", + "description": "Field name to typed value. Omitted fields retain their existing values; explicit null clears an optional field.", + "additionalProperties": {} + }, + "readOnlyFields": { + "type": "array", + "description": "Field names that cannot be changed for this row.", + "items": { + "type": "string" + } + }, + "readOnlyReason": { + "type": "string", + "description": "Explain why the indicated fields are read-only." + } + } + }, + "PreferenceSecretV1": { + "type": "object", + "properties": { + "label": { + "type": "string", + "description": "Human-readable secret label." + }, + "value": { + "type": "string", + "description": "Shown once. Clients must not store, log, cache, or send this secret to analytics." + }, + "masked": { + "type": "string", + "description": "Masked representation, for example qqq_…7f3a." + }, + "usageText": { + "type": "string", + "description": "Usage guidance such as a curl example; may contain newlines." + } + } + }, + "PreferenceSectionPatchRequestV1": { + "type": "object", + "description": "Partial update for the signed-in user only. Unknown properties, fields, lists and rows, including userId, are rejected with 400. All validation errors are returned together; omitted fields and rows are unchanged.", + "properties": { + "values": { + "type": "object", + "description": "Changed scalar fields only. Explicit null clears an optional field. Types, required, maxLength, ENUM membership and editability are validated.", + "additionalProperties": {} + }, + "lists": { + "type": "object", + "description": "List name to changed fixed rows. No add or remove operation is supported.", + "additionalProperties": { + "type": "array", + "items": { + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "Required fixed row key from the section response. No new rows can be created." + }, + "values": { + "type": "object", + "description": "Changed row fields only. Read-only fields are rejected.", + "additionalProperties": {} + } + }, + "additionalProperties": false + } + } + } + }, + "additionalProperties": false + }, + "PreferenceSectionV1": { + "type": "object", + "description": "One visible section with the signed-in user's current preferences.", + "properties": { + "showInUserMenu": { + "type": "boolean", + "description": "Add a user-menu entry using the section label and icon to open this section; defaults to false." + }, + "name": { + "type": "string", + "description": "Stable section name used in URLs." + }, + "label": { + "type": "string", + "description": "Human-readable section title." + }, + "description": { + "type": "string", + "description": "Explanation for clients to display." + }, + "appName": { + "type": "string", + "description": "Optional owning application name." + }, + "icon": { + "$ref": "#/components/schemas/Icon" + }, + "order": { + "type": "integer", + "description": "Display order, ascending then label; defaults to 100." + }, + "fields": { + "type": "array", + "description": "Scalar field definitions with editability, type, defaults and validation.", + "items": { + "$ref": "#/components/schemas/FieldMetaData" + } + }, + "values": { + "type": "object", + "description": "Field name to typed value. Omitted fields retain their existing values; explicit null clears an optional field.", + "additionalProperties": {} + }, + "actions": { + "type": "array", + "description": "Registered section, list and row actions, ordered by order then label.", + "items": { + "$ref": "#/components/schemas/PreferenceActionV1" + } + }, + "lists": { + "type": "array", + "description": "Optional fixed-row preference lists.", + "items": { + "$ref": "#/components/schemas/PreferenceListV1" + } + }, + "possibleValues": { + "type": "object", + "description": "Every ENUM possible-value source referenced by scalar, list or action input fields, keyed by source name.", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PossibleValueOption" + } + } + } + } + }, + "PreferencesResponseV1": { + "type": "object", + "description": "Visible sections in display order, with only the signed-in user's values.", + "properties": { + "sections": { + "type": "array", + "description": "Installed sections the session may access; an empty list is valid.", + "items": { + "$ref": "#/components/schemas/PreferenceSectionV1" + } + } + } + }, + "ProcessCancelResponseV1": { + "type": "object" + }, + "ProcessCapabilityV1": { + "type": "object", + "properties": { + "available": { + "type": "boolean", + "description": "True when the process exists and the user may run it.", + "nullable": true + }, + "processName": { + "type": "string", + "description": "The process to run (present only when available)." + } + } + }, + "ProcessJobLaunchResponseV1": { + "type": "object", + "properties": { + "jobId": { + "type": "number", + "description": "Id of the new durable job (a jobs_job record; read it with GET /table/jobs_job/{jobId})." + }, + "status": { + "type": "string", + "description": "Status of the new job: QUEUED, or AWAITING_CONFIRMATION for a launch from the assistant channel." + } + } + }, + "ProcessMetaData": { + "type": "object", + "properties": { + "durableJobAlways": { + "type": "boolean", + "description": "True when the process always runs as a durable background job (too large to run while the user waits).", + "nullable": true + }, + "durableJobEligible": { + "type": "boolean", + "description": "True when the process can run as a durable background job (POST /processes/{processName}/jobs): clients may offer \"Run in background\".", + "nullable": true + }, + "frontendSteps": { + "type": "array", + "description": "Frontend steps (aka, Screens) for this process.", + "items": { + "$ref": "#/components/schemas/FrontendStep" + } + }, + "hasPermission": { + "type": "boolean", + "description": "Boolean to indicate if the user has permission for the process.", + "nullable": true + }, + "helpContents": { + "type": "object", + "description": "Help entries by slot, filtered for the current session.", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + } + }, + "icon": { + "description": "Icon to display for the process.", + "$ref": "#/components/schemas/Icon" + }, + "iconName": { + "type": "string", + "description": "Material UI icon name (web); prefer iconSemanticName" + }, + "iconSemanticName": { + "type": "string", + "description": "Client-neutral kebab-case icon token; null when unmapped." + }, + "isHidden": { + "type": "boolean", + "description": "Boolean indicator of whether the process should be shown to users or not", + "nullable": true + }, + "label": { + "type": "string", + "description": "User-facing name for this process" + }, + "maxInputRecords": { + "type": "number", + "description": "Most input records the process runs with, when it has a maximum." + }, + "minInputRecords": { + "type": "number", + "description": "Fewest input records the process runs with (for processes on a table's records)." + }, + "name": { + "type": "string", + "description": "Unique name for this process within the QQQ Instance" + }, + "stepFlow": { + "type": "string", + "description": "Indicator of the Step Flow used by the process. Possible values are: LINEAR, STATE_MACHINE." + }, + "tableName": { + "type": "string", + "description": "If this process is associated with a table, the table name is given here" + } + } + }, + "ProcessMetaDataAdjustment": { + "type": "object", + "properties": { + "updatedFields": { + "type": "object", + "description": "Fields whose meta-data has changed. e.g., changing a label, or required status, or inline-possible-values.", + "additionalProperties": { + "$ref": "#/components/schemas/FieldMetaData" + } + }, + "updatedFrontendStepList": { + "type": "array", + "description": "In case the backend has changed the list of frontend steps, it will be set in this field.", + "items": { + "$ref": "#/components/schemas/FrontendStep" + } + } + } + }, + "ProcessMetaDataLight": { + "type": "object", + "properties": { + "durableJobAlways": { + "type": "boolean", + "description": "True when the process always runs as a durable background job (too large to run while the user waits).", + "nullable": true + }, + "durableJobEligible": { + "type": "boolean", + "description": "True when the process can run as a durable background job (POST /processes/{processName}/jobs): clients may offer \"Run in background\".", + "nullable": true + }, + "hasPermission": { + "type": "boolean", + "description": "Boolean to indicate if the user has permission for the process.", + "nullable": true + }, + "helpContents": { + "type": "object", + "description": "Help entries by slot, filtered for the current session.", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + } + }, + "icon": { + "description": "Icon to display for the process.", + "$ref": "#/components/schemas/Icon" + }, + "iconName": { + "type": "string", + "description": "Material UI icon name (web); prefer iconSemanticName" + }, + "iconSemanticName": { + "type": "string", + "description": "Client-neutral kebab-case icon token; null when unmapped." + }, + "isHidden": { + "type": "boolean", + "description": "Boolean indicator of whether the process should be shown to users or not", + "nullable": true + }, + "label": { + "type": "string", + "description": "User-facing name for this process" + }, + "maxInputRecords": { + "type": "number", + "description": "Most input records the process runs with, when it has a maximum." + }, + "minInputRecords": { + "type": "number", + "description": "Fewest input records the process runs with (for processes on a table's records)." + }, + "name": { + "type": "string", + "description": "Unique name for this process within the QQQ Instance" + }, + "stepFlow": { + "type": "string", + "description": "Indicator of the Step Flow used by the process. Possible values are: LINEAR, STATE_MACHINE." + }, + "tableName": { + "type": "string", + "description": "If this process is associated with a table, the table name is given here" + } + } + }, + "ProcessMetaDataResponseV1": { + "type": "object", + "properties": { + "durableJobAlways": { + "type": "boolean", + "description": "True when the process always runs as a durable background job (too large to run while the user waits).", + "nullable": true + }, + "durableJobEligible": { + "type": "boolean", + "description": "True when the process can run as a durable background job (POST /processes/{processName}/jobs): clients may offer \"Run in background\".", + "nullable": true + }, + "frontendSteps": { + "type": "array", + "description": "Frontend steps (aka, Screens) for this process.", + "items": { + "$ref": "#/components/schemas/FrontendStep" + } + }, + "hasPermission": { + "type": "boolean", + "description": "Boolean to indicate if the user has permission for the process.", + "nullable": true + }, + "helpContents": { + "type": "object", + "description": "Help entries by slot, filtered for the current session.", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + } + }, + "icon": { + "type": "object", + "description": "Icon to display for the process.", + "properties": { + "color": { + "type": "string", + "description": "A color code to use for displaying the icon" + }, + "name": { + "type": "string", + "description": "Material UI icon name (web); prefer semanticName" + }, + "path": { + "type": "string", + "description": "A path to an image file that can be requested from the server, to serve as the icon image instead of a material UI icon." + }, + "semanticName": { + "type": "string", + "description": "Client-neutral kebab-case icon token; null when unmapped." + } + } + }, + "iconName": { + "type": "string", + "description": "Material UI icon name (web); prefer iconSemanticName" + }, + "iconSemanticName": { + "type": "string", + "description": "Client-neutral kebab-case icon token; null when unmapped." + }, + "isHidden": { + "type": "boolean", + "description": "Boolean indicator of whether the process should be shown to users or not", + "nullable": true + }, + "label": { + "type": "string", + "description": "User-facing name for this process" + }, + "maxInputRecords": { + "type": "number", + "description": "Most input records the process runs with, when it has a maximum." + }, + "minInputRecords": { + "type": "number", + "description": "Fewest input records the process runs with (for processes on a table's records)." + }, + "name": { + "type": "string", + "description": "Unique name for this process within the QQQ Instance" + }, + "stepFlow": { + "type": "string", + "description": "Indicator of the Step Flow used by the process. Possible values are: LINEAR, STATE_MACHINE." + }, + "tableName": { + "type": "string", + "description": "If this process is associated with a table, the table name is given here" + } + } + }, + "ProcessRecordsResponseV1": { + "type": "object", + "properties": { + "records": { + "type": "array", + "description": "List of records from the process state", + "items": { + "$ref": "#/components/schemas/OutputRecord" + } + }, + "totalRecords": { + "type": "number", + "description": "Total number of records in the process state (before pagination)" + } + } + }, + "ProcessStepComplete": { + "type": "object", + "description": "Data returned after the job is complete (whether it was synchronous, or asynchronous)", + "properties": { + "backStep": { + "type": "string", + "description": "Name of the step the process can go back to (restart at, by stepping with isStepBack=true), when the process declares one. Omitted otherwise." + }, + "nextStep": { + "type": "string", + "description": "Name of the next process step that needs to run (a frontend step). If there are no more steps in the process, this field will not be included. " + }, + "oneTimeSecrets": { + "type": "array", + "description": "Secrets shown once in synchronous init/step responses only. Never returned by status. Clients must not cache; response uses Cache-Control: no-store.", + "items": { + "$ref": "#/components/schemas/PreferenceSecretV1" + } + }, + "processMetaDataAdjustment": { + "type": "object", + "description": "Changes to be made to the process's metaData.", + "properties": { + "updatedFields": { + "type": "object", + "description": "Fields whose meta-data has changed. e.g., changing a label, or required status, or inline-possible-values.", + "additionalProperties": { + "$ref": "#/components/schemas/FieldMetaData" + } + }, + "updatedFrontendStepList": { + "type": "array", + "description": "In case the backend has changed the list of frontend steps, it will be set in this field.", + "items": { + "type": "object", + "properties": { + "backStepName": { + "type": "string", + "description": "Name of the step a user can go back to from this step (step with isStepBack=true), when there is one." + }, + "components": { + "type": "array", + "description": "The components that make up this screen", + "items": { + "$ref": "#/components/schemas/FrontendComponent" + } + }, + "formFields": { + "type": "array", + "description": "Fields used as form fields (inputs) on this step/screen", + "items": { + "$ref": "#/components/schemas/FieldMetaData" + } + }, + "format": { + "type": "string", + "description": "An optional indicator of the screen format preferred by the application to be used for this screen. Different frontends may support different formats, and implement them differently." + }, + "helpContents": { + "type": "array", + "description": "Help content shown on the step/screen.", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + }, + "label": { + "type": "string", + "description": "The user-facing name for this step" + }, + "name": { + "type": "string", + "description": "The unique name for this step within its process" + }, + "recordListFields": { + "type": "array", + "description": "Fields used in record-lists shown on the step/screen.", + "items": { + "$ref": "#/components/schemas/FieldMetaData" + } + }, + "viewFields": { + "type": "array", + "description": "Fields used as view-only fields on this step/screen", + "items": { + "$ref": "#/components/schemas/FieldMetaData" + } + } + } + } + } + } + }, + "processUUID": { + "type": "string", + "description": "Unique identifier for a running instance the process." + }, + "type": { + "type": "string", + "description": "What kind of response has been received. Determines what additional fields will be set." + }, + "values": { + "type": "object", + "description": "Current values for fields used by the process.Keys are Strings, values can be any type, as determined by the application & process." + } + } + }, + "ProcessStepError": { + "type": "object", + "description": "In case an error is thrown in the backend job.", + "properties": { + "error": { + "type": "string", + "description": "Exception message, in case the process step threw an error." + }, + "processUUID": { + "type": "string", + "description": "Unique identifier for a running instance the process." + }, + "type": { + "type": "string", + "description": "What kind of response has been received. Determines what additional fields will be set." + }, + "userFacingError": { + "type": "string", + "description": "Optional user-facing exception message, in case the process step threw a user-facing error." + } + } + }, + "ProcessStepJobStarted": { + "type": "object", + "description": "In case the backend needs more time, this is a UUID of the background job that has been started.", + "properties": { + "jobUUID": { + "type": "string", + "description": "Unique identifier for a running step of the process. Must be passed into `status` check calls." + }, + "processUUID": { + "type": "string", + "description": "Unique identifier for a running instance the process." + }, + "type": { + "type": "string", + "description": "What kind of response has been received. Determines what additional fields will be set." + } + } + }, + "ProcessStepResponseV1": { + "oneOf": [ + { + "type": "object", + "description": "Data returned after the job is complete (whether it was synchronous, or asynchronous)", + "properties": { + "backStep": { + "type": "string", + "description": "Name of the step the process can go back to (restart at, by stepping with isStepBack=true), when the process declares one. Omitted otherwise." + }, + "nextStep": { + "type": "string", + "description": "Name of the next process step that needs to run (a frontend step). If there are no more steps in the process, this field will not be included. " + }, + "oneTimeSecrets": { + "type": "array", + "description": "Secrets shown once in synchronous init/step responses only. Never returned by status. Clients must not cache; response uses Cache-Control: no-store.", + "items": { + "$ref": "#/components/schemas/PreferenceSecretV1" + } + }, + "processMetaDataAdjustment": { + "type": "object", + "description": "Changes to be made to the process's metaData.", + "properties": { + "updatedFields": { + "type": "object", + "description": "Fields whose meta-data has changed. e.g., changing a label, or required status, or inline-possible-values.", + "additionalProperties": { + "$ref": "#/components/schemas/FieldMetaData" + } + }, + "updatedFrontendStepList": { + "type": "array", + "description": "In case the backend has changed the list of frontend steps, it will be set in this field.", + "items": { + "type": "object", + "properties": { + "backStepName": { + "type": "string", + "description": "Name of the step a user can go back to from this step (step with isStepBack=true), when there is one." + }, + "components": { + "type": "array", + "description": "The components that make up this screen", + "items": { + "$ref": "#/components/schemas/FrontendComponent" + } + }, + "formFields": { + "type": "array", + "description": "Fields used as form fields (inputs) on this step/screen", + "items": { + "$ref": "#/components/schemas/FieldMetaData" + } + }, + "format": { + "type": "string", + "description": "An optional indicator of the screen format preferred by the application to be used for this screen. Different frontends may support different formats, and implement them differently." + }, + "helpContents": { + "type": "array", + "description": "Help content shown on the step/screen.", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + }, + "label": { + "type": "string", + "description": "The user-facing name for this step" + }, + "name": { + "type": "string", + "description": "The unique name for this step within its process" + }, + "recordListFields": { + "type": "array", + "description": "Fields used in record-lists shown on the step/screen.", + "items": { + "$ref": "#/components/schemas/FieldMetaData" + } + }, + "viewFields": { + "type": "array", + "description": "Fields used as view-only fields on this step/screen", + "items": { + "$ref": "#/components/schemas/FieldMetaData" + } + } + } + } + } + } + }, + "processUUID": { + "type": "string", + "description": "Unique identifier for a running instance the process." + }, + "type": { + "type": "string", + "description": "What kind of response has been received. Determines what additional fields will be set." + }, + "values": { + "type": "object", + "description": "Current values for fields used by the process.Keys are Strings, values can be any type, as determined by the application & process." + } + } + }, + { + "type": "object", + "description": "In case the backend needs more time, this is a UUID of the background job that has been started.", + "properties": { + "jobUUID": { + "type": "string", + "description": "Unique identifier for a running step of the process. Must be passed into `status` check calls." + }, + "processUUID": { + "type": "string", + "description": "Unique identifier for a running instance the process." + }, + "type": { + "type": "string", + "description": "What kind of response has been received. Determines what additional fields will be set." + } + } + }, + { + "type": "object", + "description": "Response to a status check for a backgrounded job.", + "properties": { + "current": { + "type": "number", + "description": "Optional indicator of progress (e.g., `current` of `total`, as in (`1 of 10`)." + }, + "logTail": { + "type": "array", + "items": { + "$ref": "#/components/schemas/JobLogLineV1" + } + }, + "message": { + "type": "string", + "description": "Status message regarding the running process step." + }, + "processUUID": { + "type": "string", + "description": "Unique identifier for a running instance the process." + }, + "progress": { + "type": "object", + "properties": { + "bytesDone": { + "type": "number" + }, + "bytesTotal": { + "type": "number" + }, + "currentPhase": { + "type": "string" + }, + "done": { + "type": "number" + }, + "etaSeconds": { + "type": "number" + }, + "message": { + "type": "string" + }, + "percent": { + "type": "number" + }, + "phases": { + "type": "array", + "items": { + "$ref": "#/components/schemas/JobPhaseV1" + } + }, + "total": { + "type": "number" + }, + "unitLabel": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "total": { + "type": "number", + "description": "Optional indicator of progress (e.g., `current` of `total`, as in (`1 of 10`)." + }, + "type": { + "type": "string", + "description": "What kind of response has been received. Determines what additional fields will be set." + } + } + }, + { + "type": "object", + "description": "In case an error is thrown in the backend job.", + "properties": { + "error": { + "type": "string", + "description": "Exception message, in case the process step threw an error." + }, + "processUUID": { + "type": "string", + "description": "Unique identifier for a running instance the process." + }, + "type": { + "type": "string", + "description": "What kind of response has been received. Determines what additional fields will be set." + }, + "userFacingError": { + "type": "string", + "description": "Optional user-facing exception message, in case the process step threw a user-facing error." + } + } + } + ] + }, + "ProcessStepRunning": { + "type": "object", + "description": "Response to a status check for a backgrounded job.", + "properties": { + "current": { + "type": "number", + "description": "Optional indicator of progress (e.g., `current` of `total`, as in (`1 of 10`)." + }, + "logTail": { + "type": "array", + "items": { + "$ref": "#/components/schemas/JobLogLineV1" + } + }, + "message": { + "type": "string", + "description": "Status message regarding the running process step." + }, + "processUUID": { + "type": "string", + "description": "Unique identifier for a running instance the process." + }, + "progress": { + "type": "object", + "properties": { + "bytesDone": { + "type": "number" + }, + "bytesTotal": { + "type": "number" + }, + "currentPhase": { + "type": "string" + }, + "done": { + "type": "number" + }, + "etaSeconds": { + "type": "number" + }, + "message": { + "type": "string" + }, + "percent": { + "type": "number" + }, + "phases": { + "type": "array", + "items": { + "$ref": "#/components/schemas/JobPhaseV1" + } + }, + "total": { + "type": "number" + }, + "unitLabel": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "total": { + "type": "number", + "description": "Optional indicator of progress (e.g., `current` of `total`, as in (`1 of 10`)." + }, + "type": { + "type": "string", + "description": "What kind of response has been received. Determines what additional fields will be set." + } + } + }, + "PublicBranding": { + "type": "object", + "properties": { + "accentColor": { + "type": "string", + "description": "Primary accent color, as a CSS color value." + }, + "accentColorLight": { + "type": "string", + "description": "Light variant of the accent color, as a CSS color value." + }, + "appName": { + "type": "string", + "description": "Name of this application, for display to users." + }, + "companyName": { + "type": "string", + "description": "Name of the company that operates this application." + }, + "icon": { + "type": "string", + "description": "Path or URL of the application's small icon image." + }, + "logo": { + "type": "string", + "description": "Path or URL of the application's logo image." + } + } + }, + "QueryFilter": { + "properties": { + "booleanOperator": { + "description": "Boolean operator to apply between criteria", + "enum": [ + "AND", + "OR" + ], + "type": "string" + }, + "criteria": { + "description": "Field level criteria that make up the query filter", + "items": { + "$ref": "#/components/schemas/FilterCriteria" + }, + "type": "array" + }, + "limit": { + "description": "Maximum number of results to return.", + "type": "number" + }, + "orderBys": { + "description": "How the query's results should be ordered (sorted).", + "items": { + "$ref": "#/components/schemas/OrderBy" + }, + "type": "array" + }, + "skip": { + "description": "Records to skip (e.g., to implement pagination)", + "type": "number" + } + }, + "type": "object" + }, + "QueryJoin": { + "type": "object", + "properties": { + "alias": { + "type": "string", + "description": "Alias to apply to this table in the join query" + }, + "baseTableOrAlias": { + "type": "string", + "description": "Base table (or an alias) that this QueryJoin is joined against" + }, + "joinName": { + "type": "string", + "description": "Name of a join to use in case the baseTable and joinTable have more than one" + }, + "joinTable": { + "type": "string", + "description": "Table being joined into the query by this QueryJoin" + }, + "select": { + "type": "boolean", + "description": "Whether or not to select values from the join table", + "nullable": true + }, + "type": { + "type": "string", + "description": "Type of join being performed (SQL semantics)", + "enum": [ + "INNER", + "LEFT", + "RIGHT", + "FULL" + ] + } + } + }, + "RealtimeChannelRevokedEventV1": { + "type": "object", + "properties": { + "channel": { + "type": "string" + } + } + }, + "RealtimeEventV1": { + "type": "object", + "properties": { + "channel": { + "type": "string" + }, + "data": { + "type": "object", + "description": "dataByType: hello -> RealtimeHelloEventV1; job.progress -> RealtimeJobProgressEventV1; record.changed -> RealtimeRecordChangedEventV1; record.deleted -> RealtimeRecordDeletedEventV1; table.changed -> RealtimeTableChangedEventV1; metadata.changed -> RealtimeMetaDataChangedEventV1; session-ended -> RealtimeSessionEndedEventV1; resync -> RealtimeResyncEventV1; channel-revoked -> RealtimeChannelRevokedEventV1. Selected by the envelope's event; data has no discriminator. All properties are optional; QBits may publish additional event-specific data.", + "properties": { + "bytesDone": { + "type": "number" + }, + "bytesTotal": { + "type": "number" + }, + "changedBy": { + "type": "string" + }, + "channel": { + "type": "string" + }, + "chunksDone": { + "type": "number" + }, + "chunksTotal": { + "type": "number" + }, + "connectionId": { + "type": "string" + }, + "currentPhase": { + "type": "string" + }, + "etaSeconds": { + "type": "number" + }, + "fields": { + "type": "array", + "items": { + "type": "string" + } + }, + "generation": { + "type": "integer" + }, + "heartbeatSeconds": { + "type": "integer" + }, + "jobId": { + "type": "number" + }, + "logSeq": { + "type": "number" + }, + "message": { + "type": "string" + }, + "metaDataGeneration": { + "type": "integer" + }, + "percent": { + "type": "number" + }, + "pk": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "nullable": true + }, + "rowsDone": { + "type": "number" + }, + "rowsFailed": { + "type": "number" + }, + "rowsPerSecond": { + "type": "number" + }, + "rowsTotal": { + "type": "number" + }, + "status": { + "type": "string" + }, + "table": { + "type": "string" + }, + "version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "nullable": true + } + } + }, + "event": { + "type": "string" + } + } + }, + "RealtimeHelloEventV1": { + "type": "object", + "properties": { + "connectionId": { + "type": "string" + }, + "heartbeatSeconds": { + "type": "integer" + }, + "metaDataGeneration": { + "type": "integer" + } + } + }, + "RealtimeJobProgressEventV1": { + "type": "object", + "properties": { + "bytesDone": { + "type": "number" + }, + "bytesTotal": { + "type": "number" + }, + "chunksDone": { + "type": "number" + }, + "chunksTotal": { + "type": "number" + }, + "currentPhase": { + "type": "string" + }, + "etaSeconds": { + "type": "number" + }, + "jobId": { + "type": "number" + }, + "logSeq": { + "type": "number" + }, + "message": { + "type": "string" + }, + "percent": { + "type": "number" + }, + "rowsDone": { + "type": "number" + }, + "rowsFailed": { + "type": "number" + }, + "rowsPerSecond": { + "type": "number" + }, + "rowsTotal": { + "type": "number" + }, + "status": { + "type": "string" + } + } + }, + "RealtimeMetaDataChangedEventV1": { + "type": "object", + "properties": { + "generation": { + "type": "integer" + } + } + }, + "RealtimeRecordChangedEventV1": { + "type": "object", + "properties": { + "changedBy": { + "type": "string" + }, + "fields": { + "type": "array", + "items": { + "type": "string" + } + }, + "pk": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "nullable": true + }, + "table": { + "type": "string" + }, + "version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "nullable": true + } + } + }, + "RealtimeRecordDeletedEventV1": { + "type": "object", + "properties": { + "pk": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "nullable": true + }, + "table": { + "type": "string" + } + } + }, + "RealtimeResyncEventV1": { + "type": "object" + }, + "RealtimeSessionEndedEventV1": { + "type": "object" + }, + "RealtimeSubscriptionRequestV1": { + "type": "object", + "properties": { + "add": { + "type": "array", + "items": { + "type": "string" + } + }, + "connectionId": { + "type": "string" + }, + "remove": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "RealtimeSubscriptionResponseV1": { + "type": "object", + "properties": { + "active": { + "type": "array", + "items": { + "type": "string" + } + }, + "refused": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "RealtimeTableChangedEventV1": { + "type": "object", + "properties": { + "table": { + "type": "string" + } + } + }, + "RecordAssociatedScriptLogsResponseV1": { + "type": "object", + "properties": { + "scriptLogRecords": { + "type": "array", + "description": "The script revision's logs (scriptLog records, up to 100), newest (highest id) first. Each record's values include `scriptLogLine`: the log's lines, as a list of records (each with its own `values`, e.g., `text`).", + "items": { + "$ref": "#/components/schemas/OutputRecord" + } + } + } + }, + "RecordAssociatedScriptStoreResponseV1": { + "type": "object", + "properties": { + "scriptId": { + "type": "number", + "description": "Id of the script (which is inserted, and referenced from the record, if the record did not yet reference one)." + }, + "scriptName": { + "type": "string", + "description": "Name of the script." + }, + "scriptRevisionId": { + "type": "number", + "description": "Id of the new script revision." + }, + "scriptRevisionSequenceNo": { + "type": "number", + "description": "Sequence number of the new revision within the script (1 for its first revision)." + } + } + }, + "RecordConflictV1": { + "type": "object", + "properties": { + "changedFields": { + "type": "array", + "items": { + "type": "string" + } + }, + "currentVersion": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "nullable": true + }, + "modifiedAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "nullable": true + }, + "modifiedByUserId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "nullable": true + } + } + }, + "RecordDeveloperModeAssociatedScript": { + "type": "object", + "properties": { + "associatedScript": { + "description": "Definition of the associated script, from the table's meta-data.", + "$ref": "#/components/schemas/AssociatedScriptMetaData" + }, + "script": { + "description": "The script record that the record references. Omitted if the record does not reference an existing script.", + "$ref": "#/components/schemas/OutputRecord" + }, + "scriptRevisions": { + "type": "array", + "description": "The script's revisions (scriptRevision records), newest (highest id) first. Present (possibly empty) when script is.", + "items": { + "$ref": "#/components/schemas/OutputRecord" + } + }, + "scriptType": { + "description": "The scriptType record of the associated script. Omitted if there is no such record.", + "$ref": "#/components/schemas/OutputRecord" + }, + "testInputFields": { + "type": "array", + "description": "Input fields for testing the script. Present (possibly empty) when the associated script has a script tester.", + "items": { + "$ref": "#/components/schemas/FieldMetaData" + } + }, + "testOutputFields": { + "type": "array", + "description": "Output fields from testing the script. Present (possibly empty) when the associated script has a script tester.", + "items": { + "$ref": "#/components/schemas/FieldMetaData" + } + } + } + }, + "RecordDeveloperModeResponseV1": { + "type": "object", + "properties": { + "associatedScripts": { + "type": "array", + "description": "Each of the table's associated scripts, with the script the record references (if any). Empty when the table has no associated scripts (or the instance has no script tables).", + "items": { + "$ref": "#/components/schemas/RecordDeveloperModeAssociatedScript" + } + }, + "record": { + "type": "object", + "description": "The record, with display values (and possible values translated).", + "properties": { + "associatedRecords": { + "type": "object", + "description": "Records associated with this record, keyed by association name. Each value is a list of records with the same shape as this one. Only present when associations were requested or written.", + "additionalProperties": { + "type": "array" + } + }, + "displayValues": { + "type": "object", + "description": "Formatted string versions of the values that make up the record. Keys are Strings, which match the table's field names. Values are all Strings." + }, + "errors": { + "type": "array", + "description": "Messages for errors on this record (for example on an associated record that could not be written). Omitted when there are none.", + "items": { + "type": "string" + } + }, + "recordLabel": { + "type": "string", + "description": "Label to identify the record to a user." + }, + "tableName": { + "type": "string", + "description": "Name of the table that the record is from." + }, + "values": { + "type": "object", + "description": "Raw values that make up the record. Keys are Strings, which match the table's field names. Values can be any type, as per the table's fields. Single-record responses (get, insert, update) include fields whose value is null; query results omit them." + }, + "warnings": { + "type": "array", + "description": "Messages for warnings on this record. Omitted when there are none.", + "items": { + "type": "string" + } + } + } + } + } + }, + "RecordDeveloperPanelsResponseV1": { + "type": "object", + "properties": { + "panels": { + "type": "array", + "description": "The panels that the instance's developer panel providers contribute for this record, sorted by order then title. Each panel has an id, title, order, optional icon, description and status badge (statusLabel, statusTone: INFO, SUCCESS, WARNING or ERROR), and either an error message (when its provider failed) or a list of blocks. Each block has a type and a label; KEY_VALUES blocks use items (label, value, monospace, href), TEXT blocks use text and tone, CODE blocks use language and code, TABLE blocks use columns and rows (lists of display strings), LINKS blocks use links (label, href, description, external) and ACTIONS blocks use actions (label, processName, tableName, includeRecordId, description). Hrefs are app-relative (e.g., /app/table/1) or absolute.", + "items": { + "type": "object", + "properties": { + "blocks": { + "type": "array" + }, + "description": { + "type": "string" + }, + "error": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string" + }, + "order": { + "type": "number" + }, + "statusLabel": { + "type": "string" + }, + "statusTone": { + "type": "string", + "enum": [ + "INFO", + "SUCCESS", + "WARNING", + "ERROR" + ] + }, + "title": { + "type": "string" + } + } + } + } + } + }, + "RecordFeatureSummaryV1": { + "type": "object", + "properties": { + "tableName": { + "type": "string" + }, + "primaryKey": { + "type": "string" + }, + "features": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ATTACHMENTS", + "TAGS", + "CUSTOM_FIELDS", + "COMMENTS", + "PRESENCE", + "SHARING", + "FAVORITES", + "FOLLOW", + "TIMELINE", + "RECENTS", + "TASKS", + "ASSIGNMENT" + ] + } + }, + "capabilities": { + "type": "object", + "additionalProperties": { + "type": "boolean" + } + }, + "isFavorite": { + "type": "boolean", + "nullable": true + }, + "isFollowing": { + "type": "boolean", + "nullable": true + }, + "counts": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "owner": { + "type": "string", + "nullable": true + }, + "assignee": { + "type": "string", + "nullable": true + }, + "presence": { + "type": "array", + "items": { + "type": "object", + "description": "Provider-defined presence entry: user identity and activity values.", + "additionalProperties": {} + }, + "nullable": true + }, + "extensions": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Provider-specific record feature extension values.", + "additionalProperties": true + } + } + } + }, + "RecordFeaturesV1": { + "type": "object", + "properties": { + "capabilities": { + "type": "object", + "additionalProperties": { + "type": "boolean" + } + }, + "features": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ATTACHMENTS", + "TAGS", + "CUSTOM_FIELDS", + "COMMENTS", + "PRESENCE", + "SHARING", + "FAVORITES", + "FOLLOW", + "TIMELINE", + "RECENTS", + "TASKS", + "ASSIGNMENT" + ] + } + }, + "ownership": { + "type": "object", + "properties": { + "assigneeFieldName": { + "type": "string" + }, + "ownerFieldName": { + "type": "string" + } + } + }, + "settings": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Feature-provider settings, keyed by provider-defined setting names.", + "additionalProperties": true + } + } + } + }, + "RecordSearchDetailV1": { + "type": "object", + "properties": { + "displayValue": { + "type": "string", + "description": "Display value of the field." + }, + "fieldLabel": { + "type": "string", + "description": "User-facing label of the field." + }, + "fieldName": { + "type": "string", + "description": "Name of the field." + } + } + }, + "RecordSearchHighlightMatchV1": { + "type": "object", + "properties": { + "end": { + "type": "number", + "description": "Offset just after the last matched character (exclusive)." + }, + "start": { + "type": "number", + "description": "Offset of the first matched character in the highlight text." + } + } + }, + "RecordSearchHighlightV1": { + "type": "object", + "properties": { + "fieldLabel": { + "type": "string", + "description": "User-facing label of the field." + }, + "fieldName": { + "type": "string", + "description": "Name of the field the snippet is from." + }, + "matches": { + "type": "array", + "description": "Matched spans in the text: sorted, non-overlapping character offsets (start inclusive, end exclusive).", + "items": { + "$ref": "#/components/schemas/RecordSearchHighlightMatchV1" + } + }, + "text": { + "type": "string", + "description": "Plain-text snippet of the field value (never markup; an ellipsis marks trimmed ends)." + } + } + }, + "RecordSearchProviderStatusV1": { + "type": "object", + "properties": { + "failureClass": { + "type": "string", + "description": "When the provider failed: the simple class name of the root cause (e.g., ConnectException)." + }, + "message": { + "type": "string", + "description": "When the provider failed with a user-facing error: its message (one line)." + }, + "status": { + "type": "string", + "description": "OK: the provider searched the tables it claimed. FAILED: it failed, and those tables were searched with the default search. NONE: there is no provider, or it claimed none of the searched tables.", + "enum": [ + "OK", + "FAILED", + "NONE" + ] + } + } + }, + "RecordSearchResponseV1": { + "type": "object", + "properties": { + "provider": { + "type": "object", + "description": "How the instance's record search provider fared: when its status is FAILED, the tables it claimed were searched with the default search instead (their source is FALLBACK).", + "properties": { + "failureClass": { + "type": "string", + "description": "When the provider failed: the simple class name of the root cause (e.g., ConnectException)." + }, + "message": { + "type": "string", + "description": "When the provider failed with a user-facing error: its message (one line)." + }, + "status": { + "type": "string", + "description": "OK: the provider searched the tables it claimed. FAILED: it failed, and those tables were searched with the default search. NONE: there is no provider, or it claimed none of the searched tables.", + "enum": [ + "OK", + "FAILED", + "NONE" + ] + } + } + }, + "results": { + "type": "array", + "description": "Records whose search fields match the search term, grouped by table (in instance order) and, within each table, in the requested order (RELEVANCE: the search provider's order, or by primary key for the default search; RECENT: most recently modified first).", + "items": { + "$ref": "#/components/schemas/RecordSearchResultV1" + } + }, + "tables": { + "type": "array", + "description": "A summary of each searched table, in the order of the results: how many results it returned, whether it has more, and what searched it.", + "items": { + "$ref": "#/components/schemas/RecordSearchTableSummaryV1" + } + } + } + }, + "RecordSearchResultV1": { + "type": "object", + "properties": { + "details": { + "type": "array", + "description": "Other search field values (not in the record label, and not highlighted) to show under the record label.", + "items": { + "$ref": "#/components/schemas/RecordSearchDetailV1" + } + }, + "highlights": { + "type": "array", + "description": "Plain-text snippets of the fields (other than those in the record label) that match the search term, with the matched spans.", + "items": { + "$ref": "#/components/schemas/RecordSearchHighlightV1" + } + }, + "recordId": { + "type": "string", + "description": "Primary key of the record, as a string." + }, + "recordLabel": { + "type": "string", + "description": "Label to identify the record to a user." + }, + "score": { + "type": "number", + "description": "Relevance from the record search provider (higher is better); absent for the default search." + }, + "tableLabel": { + "type": "string", + "description": "User-facing label of the table that the record is from." + }, + "tableName": { + "type": "string", + "description": "Name of the table that the record is from." + }, + "updatedAt": { + "type": "string", + "description": "When the record was last modified (ISO-8601 instant), when its table has a last-modified field the user may see." + } + } + }, + "RecordSearchTableSummaryV1": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean", + "description": "Whether the table has more matches past these results (request them with offset).", + "nullable": true + }, + "resultCount": { + "type": "number", + "description": "Number of results returned from the table." + }, + "source": { + "type": "string", + "description": "What searched the table: the record search PROVIDER, the DEFAULT search, or the default search as a FALLBACK because the provider failed.", + "enum": [ + "PROVIDER", + "DEFAULT", + "FALLBACK" + ] + }, + "tableLabel": { + "type": "string", + "description": "User-facing label of the table." + }, + "tableName": { + "type": "string", + "description": "Name of the table." + }, + "totalCount": { + "type": "number", + "description": "Approximate total number of matches in the table, when the search knows it (records the user may not read can make it high)." + } + } + }, + "RelatedRecordPicker": { + "type": "object", + "properties": { + "associationName": { + "type": "string", + "description": "The association whose rows the picker adds (MULTI_CHILD, LINK)" + }, + "canAddChildren": { + "type": "boolean", + "description": "Whether the user may add child or join rows (prepare and add routes)", + "nullable": true + }, + "canCreateTarget": { + "type": "boolean", + "description": "Whether to offer quick-create of a target record (insert route of targetTableName)", + "nullable": true + }, + "canRemoveChildren": { + "type": "boolean", + "description": "Whether the user may unlink (remove route; LINK only)", + "nullable": true + }, + "childTableName": { + "type": "string", + "description": "The child or join table new rows go into (MULTI_CHILD, LINK)" + }, + "childTargetFieldName": { + "type": "string", + "description": "The child table's field that holds the picked record's key (MULTI_CHILD, LINK)" + }, + "columns": { + "type": "array", + "description": "Target fields to show as result columns", + "items": { + "type": "string" + } + }, + "defaultFilter": { + "description": "Initial, user-editable filter; the query route returns it resolved as resolvedDefaultFilter", + "$ref": "#/components/schemas/QueryFilter" + }, + "fieldName": { + "type": "string", + "description": "The foreign-key field the picker sets (SINGLE)" + }, + "filter": { + "description": "Filter the server always applies to the picker's queries (may contain ${input.fieldName} variables, read from the parent record)", + "$ref": "#/components/schemas/QueryFilter" + }, + "label": { + "type": "string", + "description": "Dialog title, and the label of the button that opens it" + }, + "maxSelections": { + "type": "number", + "description": "Most records one add or link may pick (MULTI_CHILD, LINK)" + }, + "mode": { + "type": "string", + "description": "SINGLE: choose one record for fieldName. MULTI_CHILD: add child rows through associationName, after a review of reviewFieldNames. LINK: link and unlink through associationName (a join table)." + }, + "name": { + "type": "string", + "description": "Picker name; the {pickerName} path segment of the relatedRecordPicker routes" + }, + "previewFields": { + "type": "array", + "description": "Target fields to show for the highlighted record", + "items": { + "type": "string" + } + }, + "reviewFieldNames": { + "type": "array", + "description": "Child fields the user fills per picked record before saving (MULTI_CHILD); empty means no review step", + "items": { + "type": "string" + } + }, + "targetTableName": { + "type": "string", + "description": "The table records are picked from (read its metadata for fields, sections and quickCreateSectionName)" + }, + "thumbnailField": { + "type": "string", + "description": "Target field holding an image URL, for thumbnails" + } + } + }, + "RelatedRecordPickerAddResponseV1": { + "type": "object", + "properties": { + "records": { + "type": "array", + "description": "The inserted child or join rows", + "items": { + "$ref": "#/components/schemas/OutputRecord" + } + }, + "warnings": { + "type": "array", + "description": "Warnings from the inserts, if any", + "items": { + "type": "string" + } + } + } + }, + "RelatedRecordPickerPrepareResponseV1": { + "type": "object", + "properties": { + "records": { + "type": "array", + "description": "One unsaved child row per target id, in request order, with defaults, values copied from the target, and the parent and target keys (whose display value is the target's label)", + "items": { + "$ref": "#/components/schemas/OutputRecord" + } + }, + "reviewFieldNames": { + "type": "array", + "description": "Child fields for the user to review per row before the add route; empty means add without a review", + "items": { + "type": "string" + } + } + } + }, + "RelatedRecordPickerQueryResponseV1": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean", + "description": "Whether more records follow (request the next page with skip); there is no count", + "nullable": true + }, + "linkedIds": { + "type": "array", + "description": "Ids (as strings) of the returned records the parent already has a child or join row for (MULTI_CHILD, LINK with primaryKey)", + "items": { + "type": "string" + } + }, + "records": { + "type": "array", + "description": "One page of target records (values and display values), in order", + "items": { + "$ref": "#/components/schemas/OutputRecord" + } + }, + "resolvedDefaultFilter": { + "type": "object", + "description": "The picker's defaultFilter with its variables resolved, to start the dialog's filter from (first page only)", + "properties": { + "booleanOperator": { + "type": "string", + "description": "Boolean operator to apply between criteria", + "enum": [ + "AND", + "OR" + ] + }, + "criteria": { + "type": "array", + "description": "Field level criteria that make up the query filter", + "items": { + "$ref": "#/components/schemas/FilterCriteria" + } + }, + "limit": { + "type": "number", + "description": "Maximum number of results to return." + }, + "orderBys": { + "type": "array", + "description": "How the query's results should be ordered (sorted).", + "items": { + "$ref": "#/components/schemas/OrderBy" + } + }, + "skip": { + "type": "number", + "description": "Records to skip (e.g., to implement pagination)" + } + } + } + } + }, + "RelatedRecordPickerRemoveResponseV1": { + "type": "object", + "properties": { + "deletedCount": { + "type": "number", + "description": "How many join rows were deleted" + } + } + }, + "ReportMetaData": { + "type": "object", + "properties": { + "hasPermission": { + "type": "boolean", + "description": "Whether the user may run the report." + }, + "helpContents": { + "type": "object", + "description": "Help entries by slot, filtered for the current session.", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + } + }, + "iconName": { + "type": "string", + "description": "Material UI icon name (web); prefer iconSemanticName" + }, + "iconSemanticName": { + "type": "string", + "description": "Client-neutral kebab-case icon token; null when unmapped." + }, + "label": { + "type": "string", + "description": "User-facing name for this report." + }, + "name": { + "type": "string", + "description": "Unique name for this report within the QQQ Instance." + }, + "processName": { + "type": "string", + "description": "Process that runs this report, when it has one; otherwise it runs from GET /reports/{reportName}." + } + } + }, + "SavedViewsCapabilityV1": { + "type": "object", + "properties": { + "available": { + "type": "boolean", + "description": "True when the user may list saved views (queryProcessName can run).", + "nullable": true + }, + "deleteProcessName": { + "type": "string", + "description": "Deletes a view; absent when the user may not delete views." + }, + "queryProcessName": { + "type": "string", + "description": "Lists the views (input tableName; output savedViewList)." + }, + "storeProcessName": { + "type": "string", + "description": "Stores (inserts or updates) a view; absent when the user may not store views." + } + } + }, + "SharingCapabilityV1": { + "type": "object", + "properties": { + "available": { + "type": "boolean", + "description": "True when the table is shareable and the user may list shares.", + "nullable": true + }, + "deleteProcessName": { + "type": "string", + "description": "Removes a share." + }, + "editProcessName": { + "type": "string", + "description": "Changes a share's scope." + }, + "insertProcessName": { + "type": "string", + "description": "Adds a share (the record owner only; the server checks)." + }, + "listProcessName": { + "type": "string", + "description": "Lists a record's shares." + } + } + }, + "SupplementalInstanceMetaData": { + "type": "object", + "properties": { + "assistant": { + "type": "object", + "description": "Present (an object) when the instance has the assistant QBit's `assistant` supplemental meta-data - that is, when the assistant is installed and enabled, so a frontend may probe its routes. Always has `available: true`, plus the strings, numbers and booleans the QBit publishes for frontends.", + "additionalProperties": true + }, + "materialDashboard": { + "description": "Use uiSettings; kept for Next UI until it migrates", + "deprecated": true, + "$ref": "#/components/schemas/MaterialDashboardInstanceSettings" + }, + "materialDashboardTheme": { + "type": "object", + "description": "Use uiSettings; kept for Next UI until it migrates. The application theme from the instance's MaterialDashboardThemeMetaData supplemental meta-data, when the instance defines it. Keys are MaterialDashboardThemeMetaData property names (for example primaryColor, fontFamily, typographyH1FontSize, borderRadiusGlobal, density, customCss, brandedHeaderEnabled, sidebarBackgroundColor, tableHeaderBackgroundColor); values are strings, numbers or booleans. An explicit allow-list of the theme's visual properties; properties without a value are omitted.", + "additionalProperties": true, + "deprecated": true + }, + "uiSettings": { + "description": "Client-neutral process, query, record-view and theme settings.", + "$ref": "#/components/schemas/UiSettings" + } + } + }, + "TableApiDocumentV1": { + "type": "object", + "description": "An OpenAPI 3 document (the application API's own format, not part of this API's schema).", + "additionalProperties": true + }, + "TableApiV1": { + "type": "object", + "description": "An application API that exposes the table.", + "properties": { + "name": { + "type": "string", + "description": "The API's name (a stable key)." + }, + "label": { + "type": "string", + "description": "Label to show users." + }, + "path": { + "type": "string", + "description": "Root-relative base path of the API, e.g. `/api/`." + }, + "currentVersion": { + "type": "string", + "description": "The version the API calls current.", + "nullable": true + }, + "versions": { + "type": "array", + "description": "Every version the API serves.", + "items": { + "$ref": "#/components/schemas/TableApiVersionV1" + } + } + } + }, + "TableApiVersionV1": { + "type": "object", + "description": "One version of an API.", + "properties": { + "version": { + "type": "string", + "description": "The version, as it appears in the API's URLs." + }, + "semanticVersion": { + "type": "string", + "description": "Its semantic version, when the API declares one.", + "nullable": true + }, + "tableSpecPath": { + "type": "string", + "description": "Root-relative path of the table's OpenAPI document (JSON) in this version." + } + } + }, + "TableApisResponseV1": { + "type": "object", + "description": "The APIs that expose a table.", + "properties": { + "apis": { + "type": "array", + "description": "The APIs, by name.", + "items": { + "$ref": "#/components/schemas/TableApiV1" + } + } + } + }, + "TableCapabilitiesV1": { + "type": "object", + "properties": { + "SAVED_VIEW_DELETE_PROCESS": { + "type": "string" + }, + "SAVED_VIEW_QUERY_PROCESS": { + "type": "string" + }, + "SAVED_VIEW_STORE_PROCESS": { + "type": "string" + }, + "audits": { + "description": "Audit history of this table's records.", + "$ref": "#/components/schemas/AuditsCapabilityV1" + }, + "bulkDelete": { + "description": "Bulk delete of selected records.", + "$ref": "#/components/schemas/ProcessCapabilityV1" + }, + "bulkEdit": { + "description": "Bulk edit of selected records.", + "$ref": "#/components/schemas/ProcessCapabilityV1" + }, + "bulkEditWithFile": { + "description": "Bulk edit from a file.", + "$ref": "#/components/schemas/ProcessCapabilityV1" + }, + "bulkInsert": { + "description": "Bulk insert (load a file into the table).", + "$ref": "#/components/schemas/ProcessCapabilityV1" + }, + "savedViews": { + "description": "Saved views of this table.", + "$ref": "#/components/schemas/SavedViewsCapabilityV1" + }, + "sharing": { + "description": "Record sharing, for a shareable table.", + "$ref": "#/components/schemas/SharingCapabilityV1" + } + } + }, + "TableCountResponseV1": { + "type": "object", + "properties": { + "count": { + "type": "number", + "description": "Number (count) of records that satisfy the query request" + }, + "distinctCount": { + "type": "number", + "description": "Number (count) of distinct records that satisfy the query request. Only included if requested." + } + } + }, + "TableDeleteResponseV1": { + "type": "object", + "properties": { + "deletedRecordCount": { + "type": "number", + "description": "Number of records that were deleted" + }, + "errors": { + "type": "array", + "description": "Why records were not deleted (for example, a record that was not found). Omitted when every record was deleted.", + "items": { + "type": "string" + } + } + } + }, + "TableGetResponseV1": { + "type": "object", + "properties": { + "record": { + "type": "object", + "description": "The record that was fetched", + "properties": { + "associatedRecords": { + "type": "object", + "description": "Records associated with this record, keyed by association name. Each value is a list of records with the same shape as this one. Only present when associations were requested or written.", + "additionalProperties": { + "type": "array" + } + }, + "displayValues": { + "type": "object", + "description": "Formatted string versions of the values that make up the record. Keys are Strings, which match the table's field names. Values are all Strings." + }, + "errors": { + "type": "array", + "description": "Messages for errors on this record (for example on an associated record that could not be written). Omitted when there are none.", + "items": { + "type": "string" + } + }, + "recordLabel": { + "type": "string", + "description": "Label to identify the record to a user." + }, + "tableName": { + "type": "string", + "description": "Name of the table that the record is from." + }, + "values": { + "type": "object", + "description": "Raw values that make up the record. Keys are Strings, which match the table's field names. Values can be any type, as per the table's fields. Single-record responses (get, insert, update) include fields whose value is null; query results omit them." + }, + "warnings": { + "type": "array", + "description": "Messages for warnings on this record. Omitted when there are none.", + "items": { + "type": "string" + } + } + } + } + } + }, + "TableInsertResponseV1": { + "type": "object", + "properties": { + "record": { + "type": "object", + "description": "The record that was inserted", + "properties": { + "associatedRecords": { + "type": "object", + "description": "Records associated with this record, keyed by association name. Each value is a list of records with the same shape as this one. Only present when associations were requested or written.", + "additionalProperties": { + "type": "array" + } + }, + "displayValues": { + "type": "object", + "description": "Formatted string versions of the values that make up the record. Keys are Strings, which match the table's field names. Values are all Strings." + }, + "errors": { + "type": "array", + "description": "Messages for errors on this record (for example on an associated record that could not be written). Omitted when there are none.", + "items": { + "type": "string" + } + }, + "recordLabel": { + "type": "string", + "description": "Label to identify the record to a user." + }, + "tableName": { + "type": "string", + "description": "Name of the table that the record is from." + }, + "values": { + "type": "object", + "description": "Raw values that make up the record. Keys are Strings, which match the table's field names. Values can be any type, as per the table's fields. Single-record responses (get, insert, update) include fields whose value is null; query results omit them." + }, + "warnings": { + "type": "array", + "description": "Messages for warnings on this record. Omitted when there are none.", + "items": { + "type": "string" + } + } + } + }, + "warnings": { + "type": "array", + "description": "Any warnings that occurred during the insert", + "items": { + "type": "string" + } + } + } + }, + "TableMenu": { + "type": "object", + "properties": { + "icon": { + "description": "Icon of the menu's button.", + "$ref": "#/components/schemas/Icon" + }, + "items": { + "type": "array", + "description": "The menu's items, in order.", + "items": { + "$ref": "#/components/schemas/TableMenuItem" + } + }, + "label": { + "type": "string", + "description": "User-facing label of the menu's button." + }, + "slot": { + "type": "string", + "description": "Where the menu goes: VIEW_SCREEN_ACTIONS, VIEW_SCREEN_ADDITIONAL, QUERY_SCREEN_ACTIONS or QUERY_SCREEN_ADDITIONAL (or a slot the application defines)." + } + } + }, + "TableMenuItem": { + "type": "object", + "properties": { + "icon": { + "description": "Icon of the item, when it overrides the frontend's default.", + "$ref": "#/components/schemas/Icon" + }, + "itemType": { + "type": "string", + "description": "What the item is and how a frontend handles it: BUILT_IN (a standard action named by values.option, such as NEW, COPY, EDIT, DELETE, DEVELOPER_MODE, AUDIT, THIS_TABLE_PROCESS_LIST or ALL_TABLES_PROCESS_LIST), RUN_PROCESS (values.processName), DOWNLOAD_FILE (values.fieldName), SUB_MENU and SUB_LIST (values.items), or DIVIDER." + }, + "label": { + "type": "string", + "description": "User-facing label of the item, when it overrides the frontend's default." + }, + "values": { + "type": "object", + "description": "Item-type specific values: option for BUILT_IN, processName for RUN_PROCESS, fieldName for DOWNLOAD_FILE, and items (a list of menu items of this same shape) for SUB_MENU and SUB_LIST.", + "properties": { + "fieldName": { + "type": "string" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TableMenuItem" + } + }, + "option": { + "type": "string" + }, + "processName": { + "type": "string" + } + } + } + } + }, + "TableMetaData": { + "type": "object", + "properties": { + "associations": { + "type": "array", + "description": "Named record associations and their joins, without child record access", + "items": { + "$ref": "#/components/schemas/Association" + } + }, + "builtInViews": { + "type": "array", + "description": "Built-in views; evaluate their filters in the current session without persisting the resolved user id.", + "items": { + "$ref": "#/components/schemas/BuiltInViewV1" + } + }, + "capabilities": { + "type": "array", + "description": "List of strings describing actions that are supported by the backend application for the table.", + "items": { + "type": "string" + } + }, + "clientCapabilities": { + "description": "What a client may offer on this table beyond plain CRUD - saved views, audits, sharing and the bulk processes - with the process or table to use for each, for the current user. Clients use these instead of hard-coded process names. Since 1.6.0.", + "$ref": "#/components/schemas/TableCapabilitiesV1" + }, + "deletePermission": { + "type": "boolean", + "description": "Boolean to indicate if the user has delete permission for the table.", + "nullable": true + }, + "editPermission": { + "type": "boolean", + "description": "Boolean to indicate if the user has edit permission for the table.", + "nullable": true + }, + "exposedJoins": { + "type": "array", + "description": "Sections to organize fields on screens for this record", + "items": { + "$ref": "#/components/schemas/ExposedJoin" + } + }, + "fields": { + "type": "object", + "description": "Fields in this table", + "additionalProperties": { + "$ref": "#/components/schemas/FieldMetaData" + } + }, + "hasRestrictedFields": { + "type": "boolean", + "description": "True when any field has REVEALABLE, MASKED, or HIDDEN access for the current session.", + "nullable": true + }, + "helpContents": { + "type": "object", + "description": "Help Contents for this table.", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + } + }, + "icon": { + "description": "Icon to display for the table", + "$ref": "#/components/schemas/Icon" + }, + "insertPermission": { + "type": "boolean", + "description": "Boolean to indicate if the user has insert permission for the table.", + "nullable": true + }, + "isHidden": { + "type": "boolean", + "description": "Boolean indicator of whether the table should be shown to users or not", + "nullable": true + }, + "label": { + "type": "string", + "description": "User-facing name for this table" + }, + "menus": { + "type": "array", + "description": "Menus the table defines for screen slots (for example the record view's VIEW_SCREEN_ACTIONS menu, which replaces the default actions menu, and VIEW_SCREEN_ADDITIONAL menus). Omitted when the table defines none.", + "items": { + "$ref": "#/components/schemas/TableMenu" + } + }, + "metaDataGeneration": { + "type": "number", + "description": "Runtime metadata generation; refetch metadata when this changes." + }, + "name": { + "type": "string", + "description": "Unique name for this table within the QQQ Instance" + }, + "primaryKeyField": { + "type": "string", + "description": "Name of the primary key field in this table" + }, + "quickCreateSectionName": { + "type": "string", + "description": "Name of the section whose editable fields a quick-create form shows (else the required, editable fields)" + }, + "readPermission": { + "type": "boolean", + "description": "Boolean to indicate if the user has read permission for the table.", + "nullable": true + }, + "recordFeatures": { + "description": "Enabled record collaboration features, public settings, and this session's table capabilities.", + "$ref": "#/components/schemas/RecordFeaturesV1" + }, + "relatedRecordPickers": { + "type": "array", + "description": "Related-record pickers of this table whose target the user may read (docs/RELATED-RECORD-PICKER.md)", + "items": { + "$ref": "#/components/schemas/RelatedRecordPicker" + } + }, + "searchFields": { + "type": "array", + "description": "Names of the fields that record search (POST /search) matches for this table. Only present when the table is searchable and the user has read permission for it.", + "items": { + "type": "string" + } + }, + "sections": { + "type": "array", + "description": "Sections to organize fields on screens for this record", + "items": { + "$ref": "#/components/schemas/TableSection" + } + }, + "shareableTableMetaData": { + "type": "object", + "description": "For tables that support the sharing feature, meta-data about the sharing setup.", + "properties": { + "assetIdFieldName": { + "type": "string" + }, + "audiencePossibleValueSourceName": { + "type": "string" + }, + "audienceTypes": { + "type": "object" + }, + "audienceTypesPossibleValueSourceName": { + "type": "string" + }, + "scopeFieldName": { + "type": "string" + }, + "sharedRecordTableName": { + "type": "string" + }, + "thisTableOwnerIdFieldName": { + "type": "string" + } + } + }, + "supplementalMetaData": { + "type": "object", + "description": "Additional meta data about the table, not necessarily known to QQQ." + }, + "usesVariants": { + "type": "boolean", + "description": "Whether or not this table's backend uses variants.", + "nullable": true + }, + "variantTableLabel": { + "type": "string", + "description": "If the table uses variants, this is the user-facing label for the table that supplies variants for this table." + }, + "virtualFields": { + "type": "object", + "description": "Virtual fields in this table", + "additionalProperties": { + "$ref": "#/components/schemas/VirtualFieldMetaData" + } + } + } + }, + "TableMetaDataLight": { + "type": "object", + "properties": { + "capabilities": { + "type": "array", + "description": "List of strings describing actions that are supported by the backend application for the table.", + "items": { + "type": "string" + } + }, + "deletePermission": { + "type": "boolean", + "description": "Boolean to indicate if the user has delete permission for the table.", + "nullable": true + }, + "editPermission": { + "type": "boolean", + "description": "Boolean to indicate if the user has edit permission for the table.", + "nullable": true + }, + "helpContents": { + "type": "object", + "description": "Help Contents for this table.", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + } + }, + "icon": { + "description": "Icon to display for the table", + "$ref": "#/components/schemas/Icon" + }, + "insertPermission": { + "type": "boolean", + "description": "Boolean to indicate if the user has insert permission for the table.", + "nullable": true + }, + "isHidden": { + "type": "boolean", + "description": "Boolean indicator of whether the table should be shown to users or not", + "nullable": true + }, + "label": { + "type": "string", + "description": "User-facing name for this table" + }, + "metaDataGeneration": { + "type": "number", + "description": "Runtime metadata generation; refetch metadata when this changes." + }, + "name": { + "type": "string", + "description": "Unique name for this table within the QQQ Instance" + }, + "readPermission": { + "type": "boolean", + "description": "Boolean to indicate if the user has read permission for the table.", + "nullable": true + }, + "recordFeatures": { + "description": "Enabled record collaboration features, public settings, and this session's table capabilities.", + "$ref": "#/components/schemas/RecordFeaturesV1" + }, + "searchFields": { + "type": "array", + "description": "Names of the fields that record search (POST /search) matches for this table. Only present when the table is searchable and the user has read permission for it.", + "items": { + "type": "string" + } + }, + "variantTableLabel": { + "type": "string", + "description": "If the table uses variants, this is the user-facing label for the table that supplies variants for this table." + } + } + }, + "TableMetaDataResponseV1": { + "type": "object", + "properties": { + "associations": { + "type": "array", + "description": "Named record associations and their joins, without child record access", + "items": { + "$ref": "#/components/schemas/Association" + } + }, + "builtInViews": { + "type": "array", + "description": "Built-in views; evaluate their filters in the current session without persisting the resolved user id.", + "items": { + "$ref": "#/components/schemas/BuiltInViewV1" + } + }, + "capabilities": { + "type": "array", + "description": "List of strings describing actions that are supported by the backend application for the table.", + "items": { + "type": "string" + } + }, + "clientCapabilities": { + "type": "object", + "description": "What a client may offer on this table beyond plain CRUD - saved views, audits, sharing and the bulk processes - with the process or table to use for each, for the current user. Clients use these instead of hard-coded process names. Since 1.6.0.", + "properties": { + "SAVED_VIEW_DELETE_PROCESS": { + "type": "string" + }, + "SAVED_VIEW_QUERY_PROCESS": { + "type": "string" + }, + "SAVED_VIEW_STORE_PROCESS": { + "type": "string" + }, + "audits": { + "type": "object", + "description": "Audit history of this table's records.", + "properties": { + "available": { + "type": "boolean", + "description": "True when the user can read this table and its audits one of the two ways (the audit process enforces both). Independent of level: records of a table at level NONE can still have audits written explicitly.", + "nullable": true + }, + "detailTableName": { + "type": "string", + "description": "The audit detail table (field changes), joined to tableName." + }, + "level": { + "type": "string", + "description": "The table's audit level: NONE, RECORD or FIELD (informational: what is audited automatically)." + }, + "processName": { + "type": "string", + "description": "The process that returns a record's audits (inputs tableName, recordId); absent when the user may not run it." + }, + "tableName": { + "type": "string", + "description": "The audit table, when the user may query it directly." + } + } + }, + "bulkDelete": { + "type": "object", + "description": "Bulk delete of selected records.", + "properties": { + "available": { + "type": "boolean", + "description": "True when the process exists and the user may run it.", + "nullable": true + }, + "processName": { + "type": "string", + "description": "The process to run (present only when available)." + } + } + }, + "bulkEdit": { + "type": "object", + "description": "Bulk edit of selected records.", + "properties": { + "available": { + "type": "boolean", + "description": "True when the process exists and the user may run it.", + "nullable": true + }, + "processName": { + "type": "string", + "description": "The process to run (present only when available)." + } + } + }, + "bulkEditWithFile": { + "type": "object", + "description": "Bulk edit from a file.", + "properties": { + "available": { + "type": "boolean", + "description": "True when the process exists and the user may run it.", + "nullable": true + }, + "processName": { + "type": "string", + "description": "The process to run (present only when available)." + } + } + }, + "bulkInsert": { + "type": "object", + "description": "Bulk insert (load a file into the table).", + "properties": { + "available": { + "type": "boolean", + "description": "True when the process exists and the user may run it.", + "nullable": true + }, + "processName": { + "type": "string", + "description": "The process to run (present only when available)." + } + } + }, + "savedViews": { + "type": "object", + "description": "Saved views of this table.", + "properties": { + "available": { + "type": "boolean", + "description": "True when the user may list saved views (queryProcessName can run).", + "nullable": true + }, + "deleteProcessName": { + "type": "string", + "description": "Deletes a view; absent when the user may not delete views." + }, + "queryProcessName": { + "type": "string", + "description": "Lists the views (input tableName; output savedViewList)." + }, + "storeProcessName": { + "type": "string", + "description": "Stores (inserts or updates) a view; absent when the user may not store views." + } + } + }, + "sharing": { + "type": "object", + "description": "Record sharing, for a shareable table.", + "properties": { + "available": { + "type": "boolean", + "description": "True when the table is shareable and the user may list shares.", + "nullable": true + }, + "deleteProcessName": { + "type": "string", + "description": "Removes a share." + }, + "editProcessName": { + "type": "string", + "description": "Changes a share's scope." + }, + "insertProcessName": { + "type": "string", + "description": "Adds a share (the record owner only; the server checks)." + }, + "listProcessName": { + "type": "string", + "description": "Lists a record's shares." + } + } + } + } + }, + "deletePermission": { + "type": "boolean", + "description": "Boolean to indicate if the user has delete permission for the table.", + "nullable": true + }, + "editPermission": { + "type": "boolean", + "description": "Boolean to indicate if the user has edit permission for the table.", + "nullable": true + }, + "exposedJoins": { + "type": "array", + "description": "Sections to organize fields on screens for this record", + "items": { + "$ref": "#/components/schemas/ExposedJoin" + } + }, + "fields": { + "type": "object", + "description": "Fields in this table", + "additionalProperties": { + "$ref": "#/components/schemas/FieldMetaData" + } + }, + "hasRestrictedFields": { + "type": "boolean", + "description": "True when any field has REVEALABLE, MASKED, or HIDDEN access for the current session.", + "nullable": true + }, + "helpContents": { + "type": "object", + "description": "Help Contents for this table.", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + } + }, + "icon": { + "type": "object", + "description": "Icon to display for the table", + "properties": { + "color": { + "type": "string", + "description": "A color code to use for displaying the icon" + }, + "name": { + "type": "string", + "description": "Material UI icon name (web); prefer semanticName" + }, + "path": { + "type": "string", + "description": "A path to an image file that can be requested from the server, to serve as the icon image instead of a material UI icon." + }, + "semanticName": { + "type": "string", + "description": "Client-neutral kebab-case icon token; null when unmapped." + } + } + }, + "insertPermission": { + "type": "boolean", + "description": "Boolean to indicate if the user has insert permission for the table.", + "nullable": true + }, + "isHidden": { + "type": "boolean", + "description": "Boolean indicator of whether the table should be shown to users or not", + "nullable": true + }, + "label": { + "type": "string", + "description": "User-facing name for this table" + }, + "menus": { + "type": "array", + "description": "Menus the table defines for screen slots (for example the record view's VIEW_SCREEN_ACTIONS menu, which replaces the default actions menu, and VIEW_SCREEN_ADDITIONAL menus). Omitted when the table defines none.", + "items": { + "$ref": "#/components/schemas/TableMenu" + } + }, + "metaDataGeneration": { + "type": "number", + "description": "Runtime metadata generation; refetch metadata when this changes." + }, + "name": { + "type": "string", + "description": "Unique name for this table within the QQQ Instance" + }, + "primaryKeyField": { + "type": "string", + "description": "Name of the primary key field in this table" + }, + "quickCreateSectionName": { + "type": "string", + "description": "Name of the section whose editable fields a quick-create form shows (else the required, editable fields)" + }, + "readPermission": { + "type": "boolean", + "description": "Boolean to indicate if the user has read permission for the table.", + "nullable": true + }, + "recordFeatures": { + "$ref": "#/components/schemas/RecordFeaturesV1" + }, + "relatedRecordPickers": { + "type": "array", + "description": "Related-record pickers of this table whose target the user may read (docs/RELATED-RECORD-PICKER.md)", + "items": { + "$ref": "#/components/schemas/RelatedRecordPicker" + } + }, + "searchFields": { + "type": "array", + "description": "Names of the fields that record search (POST /search) matches for this table. Only present when the table is searchable and the user has read permission for it.", + "items": { + "type": "string" + } + }, + "sections": { + "type": "array", + "description": "Sections to organize fields on screens for this record", + "items": { + "$ref": "#/components/schemas/TableSection" + } + }, + "shareableTableMetaData": { + "type": "object", + "description": "For tables that support the sharing feature, meta-data about the sharing setup.", + "properties": { + "assetIdFieldName": { + "type": "string" + }, + "audiencePossibleValueSourceName": { + "type": "string" + }, + "audienceTypes": { + "type": "object" + }, + "audienceTypesPossibleValueSourceName": { + "type": "string" + }, + "scopeFieldName": { + "type": "string" + }, + "sharedRecordTableName": { + "type": "string" + }, + "thisTableOwnerIdFieldName": { + "type": "string" + } + } + }, + "supplementalMetaData": { + "type": "object", + "description": "Additional meta data about the table, not necessarily known to QQQ." + }, + "usesVariants": { + "type": "boolean", + "description": "Whether or not this table's backend uses variants.", + "nullable": true + }, + "variantTableLabel": { + "type": "string", + "description": "If the table uses variants, this is the user-facing label for the table that supplies variants for this table." + }, + "virtualFields": { + "type": "object", + "description": "Virtual fields in this table", + "additionalProperties": { + "$ref": "#/components/schemas/VirtualFieldMetaData" + } + } + } + }, + "TableQueryResponseV1": { + "type": "object", + "properties": { + "records": { + "type": "array", + "description": "List of records that satisfy the query request", + "items": { + "$ref": "#/components/schemas/OutputRecord" + } + } + } + }, + "TableSection": { + "type": "object", + "properties": { + "alternatives": { + "type": "object", + "description": "Alternative versions of this section for specific screens, keyed by alternative type (for example RECORD_VIEW or RECORD_EDIT). A screen of that type uses the alternative in place of this definition. Omitted when there are none.", + "additionalProperties": { + "$ref": "#/components/schemas/TableSection" + } + }, + "collapsible": { + "description": "Whether screens that can collapse sections may collapse this one, and whether it starts open. Omitted when the section defines no collapsible behavior.", + "$ref": "#/components/schemas/TableSectionCollapsible" + }, + "fieldNames": { + "type": "array", + "description": "List of field names to include in this section." + }, + "gridColumns": { + "type": "number", + "description": "Layout suggestion, for how many columns of a 12-grid this section should use." + }, + "helpContents": { + "type": "array", + "description": "Help Contents for this section table.", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + }, + "icon": { + "description": "Icon to display for the table", + "$ref": "#/components/schemas/Icon" + }, + "label": { + "type": "string", + "description": "User-facing label to display for this section" + }, + "name": { + "type": "string", + "description": "Unique identifier for this section within this table" + }, + "tier": { + "type": "string", + "description": "Importance of this section (T1, T2, or T3)" + }, + "widgetName": { + "type": "string", + "description": "Name of a widget in this QQQ instance to include in this section (instead of fields)." + } + } + }, + "TableSectionCollapsible": { + "type": "object", + "properties": { + "initiallyOpen": { + "type": "boolean", + "description": "Whether a collapsible section starts open, before the user has opened or closed it.", + "nullable": true + }, + "isCollapsible": { + "type": "boolean", + "description": "Whether screens that can collapse sections let the user collapse and expand this one.", + "nullable": true + } + } + }, + "TableUpdateResponseV1": { + "type": "object", + "properties": { + "record": { + "type": "object", + "description": "The record that was updated", + "properties": { + "associatedRecords": { + "type": "object", + "description": "Records associated with this record, keyed by association name. Each value is a list of records with the same shape as this one. Only present when associations were requested or written.", + "additionalProperties": { + "type": "array" + } + }, + "displayValues": { + "type": "object", + "description": "Formatted string versions of the values that make up the record. Keys are Strings, which match the table's field names. Values are all Strings." + }, + "errors": { + "type": "array", + "description": "Messages for errors on this record (for example on an associated record that could not be written). Omitted when there are none.", + "items": { + "type": "string" + } + }, + "recordLabel": { + "type": "string", + "description": "Label to identify the record to a user." + }, + "tableName": { + "type": "string", + "description": "Name of the table that the record is from." + }, + "values": { + "type": "object", + "description": "Raw values that make up the record. Keys are Strings, which match the table's field names. Values can be any type, as per the table's fields. Single-record responses (get, insert, update) include fields whose value is null; query results omit them." + }, + "warnings": { + "type": "array", + "description": "Messages for warnings on this record. Omitted when there are none.", + "items": { + "type": "string" + } + } + } + }, + "warnings": { + "type": "array", + "description": "Any warnings that occurred during the update", + "items": { + "type": "string" + } + } + } + }, + "TableVariant": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Identifier for the variant option (record) being used." + }, + "name": { + "type": "string", + "description": "A user-facing name (or label) for the variant option being used." + }, + "type": { + "type": "string", + "description": "Specification for the variant type (variantTypeKey from QQQ BackendVariantsConfig)" + } + } + }, + "TableVariantsResponseV1": { + "type": "object", + "properties": { + "variants": { + "type": "array", + "description": "The variants the table's backend can be scoped to - send one back as tableVariant in query, count, get and export requests. Empty (always present) when the backend does not use variants.", + "items": { + "$ref": "#/components/schemas/TableVariant" + } + } + } + }, + "UiApiExtensionInfo": { + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "A short description of the extension." + }, + "name": { + "type": "string", + "description": "The extension namespace, e.g. alerts or sql-workbench." + }, + "pathPrefix": { + "type": "string", + "description": "The path prefix of the extension operations under the API base path, e.g. /qbit/backups or /esb." + }, + "version": { + "type": "string", + "description": "The extension semantic version (MAJOR.MINOR.PATCH)." + } + } + }, + "UiSettings": { + "type": "object", + "properties": { + "processNamesToAddToAllQueryAndViewScreens": { + "type": "array", + "description": "Visible processes offered on every query and record-view screen.", + "items": { + "type": "string" + } + }, + "recordViewActionsPlacement": { + "type": "string", + "description": "Placement of record-view actions." + }, + "theme": { + "type": "object", + "description": "Configured colors and font families; no web layout or CSS settings.", + "additionalProperties": { + "type": "string" + } + }, + "weekdayCriteriaSettings": { + "description": "Weekday query criteria configuration.", + "$ref": "#/components/schemas/MaterialDashboardWeekdayCriteriaSettings" + } + } + }, + "UploadRefResponseV1": { + "type": "object", + "properties": { + "contentType": { + "type": "string", + "description": "The file's content type, as uploaded." + }, + "expiresAt": { + "type": "string", + "description": "When the ref stops working (ISO-8601). A job that uses it extends it." + }, + "fileName": { + "type": "string", + "description": "The file's name." + }, + "ref": { + "type": "string", + "description": "Opaque ref to the uploaded file, bound to the uploading user. Pass it in uploadRefs." + }, + "sizeBytes": { + "type": "number", + "description": "The file's size in bytes." + } + } + }, + "VersionResponseV1": { + "type": "object", + "properties": { + "apiVersion": { + "type": "string", + "description": "Semantic version (MAJOR.MINOR.PATCH) of the UI API this server implements. MAJOR matches the URL version (v1). A client built against 1.x works with any server 1.y where y >= x." + }, + "basePath": { + "type": "string", + "description": "Base path of this API version, e.g. /qqq/v1." + }, + "clientChannels": { + "type": "array", + "description": "Client channel names the server accepts in the X-QQQ-Client request header (`channel[/detail]`, e.g. next-ui, assistant/). A client names itself on every request; it is recorded in audits and some objects are denied to some channels. The actor is always the signed-in user; a channel never grants anything.", + "items": { + "type": "string" + } + }, + "extensions": { + "type": "array", + "description": "Extensions (modules and qbits) registered on this server, each with its own path prefix and semantic version.", + "items": { + "$ref": "#/components/schemas/UiApiExtensionInfo" + } + }, + "features": { + "type": "array", + "description": "Names of the optional core features this server supports, so a client can show or hide an area without probing.", + "items": { + "type": "string" + } + }, + "supportedMajorVersions": { + "type": "array", + "description": "The major versions of the UI API this server serves.", + "items": { + "type": "number" + } + } + } + }, + "VirtualFieldMetaData": { + "type": "object", + "properties": { + "accessTier": { + "type": "string", + "description": "Effective field access: FULL, REVEALABLE, MASKED, or HIDDEN. Omitted means FULL. Restricted values are strings, regardless of field type.", + "enum": [ + "FULL", + "REVEALABLE", + "MASKED", + "HIDDEN" + ] + }, + "adornments": { + "type": "array", + "description": "Special UI dressings to add to the field.", + "items": { + "$ref": "#/components/schemas/FieldAdornment" + } + }, + "allowedFilterOperators": { + "type": "array", + "description": "Allowed filter operators when restricted: EQUALS and IN for REVEALABLE when exact match is enabled, otherwise empty. Omitted means unrestricted.", + "items": { + "type": "string" + } + }, + "behaviors": { + "type": "array", + "description": "Names of the field's behaviors that a frontend applies while editing, e.g., TO_UPPER_CASE, TO_LOWER_CASE or TRIM. Absent when the field has none.", + "items": { + "type": "string" + } + }, + "defaultValue": { + "type": "string", + "description": "Default value to use in this field." + }, + "displayFormat": { + "type": "string", + "description": "C-style format specifier for displaying values in this field." + }, + "gridColumns": { + "type": "number", + "description": "Width of this field in a 12-column record form or view grid (e.g., 12 for the full width, 6 for half). Absent when the frontend's default applies." + }, + "helpContents": { + "type": "array", + "description": "Help Contents for this field.", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + }, + "inlinePossibleValueSource": { + "type": "object", + "description": "Inline possible-value source for this field; enumValues supply choices without a separate lookup.", + "properties": { + "customCodeReference": { + "type": "object", + "properties": { + "codeType": { + "type": "string", + "enum": [ + "JAVA", + "JAVA_SCRIPT" + ] + }, + "inlineCode": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "enumValues": { + "type": "array" + }, + "helpContent": { + "type": "object" + }, + "idType": { + "type": "string", + "enum": [ + "STRING", + "INTEGER", + "LONG", + "DECIMAL", + "BOOLEAN", + "DATE", + "TIME", + "DATE_TIME", + "TEXT", + "HTML", + "PASSWORD", + "BLOB" + ] + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "orderByFields": { + "type": "array" + }, + "overrideIdField": { + "type": "string" + }, + "picker": { + "type": "object", + "properties": { + "detailFields": { + "type": "array" + }, + "filterFields": { + "type": "array" + }, + "pageSize": { + "type": "number" + }, + "previewField": { + "type": "string" + }, + "searchFields": { + "type": "array" + }, + "sorts": { + "type": "array" + }, + "subtitleFields": { + "type": "array" + }, + "thumbnailField": { + "type": "string" + }, + "uploadProcessName": { + "type": "string" + }, + "uploadResultIdField": { + "type": "string" + } + } + }, + "searchFields": { + "type": "array" + }, + "tableName": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "ENUM", + "TABLE", + "CUSTOM" + ] + }, + "valueFields": { + "type": "array" + }, + "valueFieldsIfNotFound": { + "type": "array" + }, + "valueFormat": { + "type": "string" + }, + "valueFormatIfNotFound": { + "type": "string" + } + } + }, + "isEditable": { + "type": "boolean", + "description": "Indicate if user may edit the value in this field.", + "nullable": true + }, + "isHeavy": { + "type": "boolean", + "description": "Indicator of 'heavy' fields, which are not loaded by default. e.g., some blobs or long-texts", + "nullable": true + }, + "isHidden": { + "type": "boolean", + "description": "Indicate if this field should be hidden from users", + "nullable": true + }, + "isQueryCriteria": { + "type": "boolean", + "description": "Indicator of whether or not this virtual field can be included as a query filter criteria", + "nullable": true + }, + "isQuerySelectable": { + "type": "boolean", + "description": "Indicator of whether or not this virtual field can be included in query outputs (e.g., if it can be selected, in the SQL sense)", + "nullable": true + }, + "isRequired": { + "type": "boolean", + "description": "Indicate if a value in this field is required.", + "nullable": true + }, + "isSortable": { + "type": "boolean", + "description": "False for restricted fields; omitted means sortable.", + "nullable": true + }, + "label": { + "type": "string", + "description": "User-facing name for this field" + }, + "maxLength": { + "type": "number", + "description": "For String fields, the max length the field supports." + }, + "maxValue": { + "type": "string", + "description": "For number fields, the largest value the field accepts (inclusive). Absent when there is no such limit." + }, + "minValue": { + "type": "string", + "description": "For number fields, the smallest value the field accepts (inclusive). Absent when there is no such limit." + }, + "name": { + "type": "string", + "description": "Unique name for this field within its container (table or process)" + }, + "picker": { + "type": "object", + "description": "When this field's possible value source declares a record picker (for sources over large tables), its configuration: thumbnail, preview, subtitle and detail fields, filter fields, search fields, sorts and page size. Frontends offer a searchable, paged picker dialog.", + "properties": { + "detailFields": { + "type": "array" + }, + "filterFields": { + "type": "array" + }, + "pageSize": { + "type": "number" + }, + "previewField": { + "type": "string" + }, + "searchFields": { + "type": "array" + }, + "sorts": { + "type": "array" + }, + "subtitleFields": { + "type": "array" + }, + "thumbnailField": { + "type": "string" + }, + "uploadProcessName": { + "type": "string" + }, + "uploadResultIdField": { + "type": "string" + } + } + }, + "pickerTableName": { + "type": "string", + "description": "When this field has a picker, the table its possible value source reads, whose metadata describes the picker's fields." + }, + "possibleValueSourceDependencyBehavior": { + "type": "string", + "description": "DISABLE_UNTIL_SET disables a contingent field until its dependencies are set (default). SHOW_ALL_UNTIL_SET keeps it enabled and omits criteria with missing inputs in form searches. Absent for non-contingent fields.", + "enum": [ + "DISABLE_UNTIL_SET", + "SHOW_ALL_UNTIL_SET" + ] + }, + "possibleValueSourceDependsOn": { + "type": "array", + "description": "Names of fields controlling this field's choices, including explicit and filter dependencies. Absent for non-contingent fields.", + "items": { + "type": "string" + } + }, + "possibleValueSourceName": { + "type": "string", + "description": "If this field's values should come from a possible value source, then that PVS is named here." + }, + "supplementalMetaData": { + "type": "object", + "description": "Additional frontend-visible metadata for this field, keyed by supplemental type." + }, + "type": { + "type": "string", + "description": "Data-type for this field" + }, + "validation": { + "description": "The field's validation rules, as the server enforces them on insert and update (required, maxLength and tooLongBehavior, min/max value, pattern). Absent when the field has none. Since 1.6.0.", + "$ref": "#/components/schemas/FieldValidationV1" + } + } + }, + "WeekdayCriteriaArguments": { + "type": "object", + "properties": { + "timeZoneId": { + "type": "string" + }, + "useSessionZoneId": { + "type": "boolean" + } + }, + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ] + } + }, + "WidgetBlock": { + "type": "object", + "properties": { + "blockId": { + "type": "string", + "description": "Unique identifier for this block within it widget. Used as a key for helpContents." + }, + "blockType": { + "type": "string", + "description": "What type of block to render.", + "enum": [ + "BUTTON", + "AUDIO", + "BIG_NUMBER", + "COMPOSITE", + "DIVIDER", + "IMAGE", + "INPUT_FIELD", + "NUMBER_ICON_BADGE", + "PROGRESS_BAR", + "TABLE_SUB_ROW_DETAIL_ROW", + "TEXT", + "UP_OR_DOWN_NUMBER" + ] + }, + "blockTypeName": { + "type": "string", + "description": "Name of the block's type, as the backend declares it (including types this API version does not enumerate in blockType)." + }, + "conditional": { + "type": "string", + "description": "Optional field name (e.g,. from a process's set of fields) to act as a 'guard' for the block - e.g., only include it in the UI if the value for this field is true" + }, + "footerText": { + "type": "string", + "description": "Footer as plain text." + }, + "layout": { + "type": "string", + "description": "For COMPOSITE type blocks, an indicator of how the sub-blocks should be laid out", + "enum": [ + "FLEX_COLUMN", + "FLEX_ROW_WRAPPED", + "FLEX_ROW_SPACE_BETWEEN", + "FLEX_ROW_CENTER", + "TABLE_SUB_ROW_DETAILS", + "BADGES_WRAPPER" + ] + }, + "modalMode": { + "type": "string", + "description": "For COMPOSITE type blocks, optional control to make the widget appear modally", + "enum": [ + "MODAL" + ] + }, + "overlayHtml": { + "type": "string", + "description": "Composite overlay as HTML." + }, + "overlayText": { + "type": "string", + "description": "Composite overlay as plain text." + }, + "styles": { + "description": "Styles to apply to the block. Different fields based on blockType.", + "oneOf": [ + { + "type": "object", + "properties": { + "backgroundColor": { + "type": "string", + "description": "A background color to use for the block" + }, + "padding": { + "type": "object", + "description": "Optional padding to apply to the block", + "properties": { + "bottom": { + "type": "object" + }, + "left": { + "type": "object" + }, + "right": { + "type": "object" + }, + "top": { + "type": "object" + } + } + } + } + }, + { + "type": "object", + "properties": { + "color": { + "type": "string", + "description": "A Color to use for the button. May be specified as a StandardColor (one of: SUCCESS, WARNING, ERROR, INFO, MUTED) or an RGB code." + }, + "format": { + "type": "string", + "description": "An optional indicator of the screen format preferred by the application to be used for this block, such as OUTLINED, FILLED, or TEXT. Different frontends may support different formats, and implement them differently." + } + } + }, + { + "type": "object", + "properties": { + "height": { + "type": "string", + "description": "A request to render the image at a specified height." + }, + "padding": { + "type": "object", + "description": "Optional padding to apply to the image", + "properties": { + "bottom": { + "type": "object" + }, + "left": { + "type": "object" + }, + "right": { + "type": "object" + }, + "top": { + "type": "object" + } + } + }, + "width": { + "type": "string", + "description": "A request to render the image at a specified width." + } + } + }, + { + "type": "object", + "properties": { + "color": { + "type": "string", + "description": "A Color to display the text in. May be specified as a StandardColor (one of: SUCCESS, WARNING, ERROR, INFO, MUTED) or an RGB code." + }, + "format": { + "type": "string", + "description": "An optional indicator of the screen format preferred by the application to be used for this block. Different frontends may support different formats, and implement them differently." + }, + "size": { + "type": "string", + "description": "An optional indicator of the size at which the text should be rendered. May be a named value (one oflargest, headline, title, body, smallest) or a numeric size - both are up to the frontend to interpret." + }, + "weight": { + "type": "string", + "description": "An optional indicator of the weight at which the text should be rendered. May be a named value (one ofextralight, thin, medium, black, semibold, bold, extrabold) or a numeric, e.g., 100, 200, ..., 900" + } + } + } + ], + "$ref": "#/components/schemas/WidgetBlockStyles" + }, + "subBlocks": { + "type": "array", + "description": "For COMPOSITE type blocks, a list of sub-blocks.", + "items": { + "$ref": "#/components/schemas/WidgetBlock" + } + }, + "values": { + "description": "Values to show in the block, or otherwise control its behavior. Different fields based on blockType.", + "oneOf": [ + { + "type": "object", + "description": "Values used for an AUDIO type widget block", + "properties": { + "autoPlay": { + "type": "boolean", + "description": "Control if the file should automatically play when the block is rendered", + "nullable": true + }, + "path": { + "type": "string", + "description": "The path to the audio file on the server" + }, + "showControls": { + "type": "boolean", + "description": "Control if on-screen controls should be shown to allow the user to control playback", + "nullable": true + } + } + }, + { + "type": "object", + "description": "Values used for a BUTTON type widget block", + "properties": { + "actionCode": { + "type": "string", + "description": "Code used within the app as the value submitted when the button is clicked" + }, + "controlCode": { + "type": "string", + "description": "Instructions for what should happen in the frontend (e.g., within a screen), when the button is clicked.\n\nTo show a modal composite block, use format: `showModal:${blockId}` (e.g., `showModal:myBlock`)\n\nTo hide a modal composite block, use format: `hideModal:${blockId}` (e.g., `hideModal:myBlock`)\n\nTo toggle visibility of a modal composite block, use format: `toggleModal:${blockId}` (e.g., `toggleModal:myBlock`)\n" + }, + "endIcon": { + "type": "object", + "description": "An optional icon to display after the text in the button", + "properties": { + "color": { + "type": "string", + "description": "A color code to use for displaying the icon" + }, + "name": { + "type": "string", + "description": "Material UI icon name (web); prefer semanticName" + }, + "path": { + "type": "string", + "description": "A path to an image file that can be requested from the server, to serve as the icon image instead of a material UI icon." + }, + "semanticName": { + "type": "string", + "description": "Client-neutral kebab-case icon token; null when unmapped." + } + } + }, + "label": { + "type": "string", + "description": "User-facing label to display in the button" + }, + "startIcon": { + "type": "object", + "description": "An optional icon to display before the text in the button", + "properties": { + "color": { + "type": "string", + "description": "A color code to use for displaying the icon" + }, + "name": { + "type": "string", + "description": "Material UI icon name (web); prefer semanticName" + }, + "path": { + "type": "string", + "description": "A path to an image file that can be requested from the server, to serve as the icon image instead of a material UI icon." + }, + "semanticName": { + "type": "string", + "description": "Client-neutral kebab-case icon token; null when unmapped." + } + } + } + } + }, + { + "type": "object", + "description": "Values used for an IMAGE type widget block", + "properties": { + "path": { + "type": "string", + "description": "The path to the image on the server" + } + } + }, + { + "type": "object", + "description": "Values used for an INPUT_FIELD type widget block", + "properties": { + "autoFocus": { + "type": "boolean", + "description": "Indicate whether this field should auto-focus when it is rendered", + "nullable": true + }, + "fieldMetaData": { + "type": "object", + "description": "Metadata to define the field that this block controls", + "properties": { + "accessTier": { + "type": "string", + "description": "Effective field access: FULL, REVEALABLE, MASKED, or HIDDEN. Omitted means FULL. Restricted values are strings, regardless of field type.", + "enum": [ + "FULL", + "REVEALABLE", + "MASKED", + "HIDDEN" + ] + }, + "adornments": { + "type": "array", + "description": "Special UI dressings to add to the field.", + "items": { + "$ref": "#/components/schemas/FieldAdornment" + } + }, + "allowedFilterOperators": { + "type": "array", + "description": "Allowed filter operators when restricted: EQUALS and IN for REVEALABLE when exact match is enabled, otherwise empty. Omitted means unrestricted.", + "items": { + "type": "string" + } + }, + "behaviors": { + "type": "array", + "description": "Names of the field's behaviors that a frontend applies while editing, e.g., TO_UPPER_CASE, TO_LOWER_CASE or TRIM. Absent when the field has none.", + "items": { + "type": "string" + } + }, + "defaultValue": { + "type": "string", + "description": "Default value to use in this field." + }, + "displayFormat": { + "type": "string", + "description": "C-style format specifier for displaying values in this field." + }, + "gridColumns": { + "type": "number", + "description": "Width of this field in a 12-column record form or view grid (e.g., 12 for the full width, 6 for half). Absent when the frontend's default applies." + }, + "helpContents": { + "type": "array", + "description": "Help Contents for this field.", + "items": { + "$ref": "#/components/schemas/HelpContentV1" + } + }, + "inlinePossibleValueSource": { + "type": "object", + "description": "Inline possible-value source for this field; enumValues supply choices without a separate lookup.", + "properties": { + "customCodeReference": { + "type": "object", + "properties": { + "codeType": { + "type": "string", + "enum": [ + "JAVA", + "JAVA_SCRIPT" + ] + }, + "inlineCode": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "enumValues": { + "type": "array" + }, + "helpContent": { + "type": "object" + }, + "idType": { + "type": "string", + "enum": [ + "STRING", + "INTEGER", + "LONG", + "DECIMAL", + "BOOLEAN", + "DATE", + "TIME", + "DATE_TIME", + "TEXT", + "HTML", + "PASSWORD", + "BLOB" + ] + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "orderByFields": { + "type": "array" + }, + "overrideIdField": { + "type": "string" + }, + "picker": { + "type": "object", + "properties": { + "detailFields": { + "type": "array" + }, + "filterFields": { + "type": "array" + }, + "pageSize": { + "type": "number" + }, + "previewField": { + "type": "string" + }, + "searchFields": { + "type": "array" + }, + "sorts": { + "type": "array" + }, + "subtitleFields": { + "type": "array" + }, + "thumbnailField": { + "type": "string" + }, + "uploadProcessName": { + "type": "string" + }, + "uploadResultIdField": { + "type": "string" + } + } + }, + "searchFields": { + "type": "array" + }, + "tableName": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "ENUM", + "TABLE", + "CUSTOM" + ] + }, + "valueFields": { + "type": "array" + }, + "valueFieldsIfNotFound": { + "type": "array" + }, + "valueFormat": { + "type": "string" + }, + "valueFormatIfNotFound": { + "type": "string" + } + } + }, + "isEditable": { + "type": "boolean", + "description": "Indicate if user may edit the value in this field.", + "nullable": true + }, + "isHeavy": { + "type": "boolean", + "description": "Indicator of 'heavy' fields, which are not loaded by default. e.g., some blobs or long-texts", + "nullable": true + }, + "isHidden": { + "type": "boolean", + "description": "Indicate if this field should be hidden from users", + "nullable": true + }, + "isRequired": { + "type": "boolean", + "description": "Indicate if a value in this field is required.", + "nullable": true + }, + "isSortable": { + "type": "boolean", + "description": "False for restricted fields; omitted means sortable.", + "nullable": true + }, + "label": { + "type": "string", + "description": "User-facing name for this field" + }, + "maxLength": { + "type": "number", + "description": "For String fields, the max length the field supports." + }, + "maxValue": { + "type": "string", + "description": "For number fields, the largest value the field accepts (inclusive). Absent when there is no such limit." + }, + "minValue": { + "type": "string", + "description": "For number fields, the smallest value the field accepts (inclusive). Absent when there is no such limit." + }, + "name": { + "type": "string", + "description": "Unique name for this field within its container (table or process)" + }, + "picker": { + "type": "object", + "description": "When this field's possible value source declares a record picker (for sources over large tables), its configuration: thumbnail, preview, subtitle and detail fields, filter fields, search fields, sorts and page size. Frontends offer a searchable, paged picker dialog.", + "properties": { + "detailFields": { + "type": "array" + }, + "filterFields": { + "type": "array" + }, + "pageSize": { + "type": "number" + }, + "previewField": { + "type": "string" + }, + "searchFields": { + "type": "array" + }, + "sorts": { + "type": "array" + }, + "subtitleFields": { + "type": "array" + }, + "thumbnailField": { + "type": "string" + }, + "uploadProcessName": { + "type": "string" + }, + "uploadResultIdField": { + "type": "string" + } + } + }, + "pickerTableName": { + "type": "string", + "description": "When this field has a picker, the table its possible value source reads, whose metadata describes the picker's fields." + }, + "possibleValueSourceDependencyBehavior": { + "type": "string", + "description": "DISABLE_UNTIL_SET disables a contingent field until its dependencies are set (default). SHOW_ALL_UNTIL_SET keeps it enabled and omits criteria with missing inputs in form searches. Absent for non-contingent fields.", + "enum": [ + "DISABLE_UNTIL_SET", + "SHOW_ALL_UNTIL_SET" + ] + }, + "possibleValueSourceDependsOn": { + "type": "array", + "description": "Names of fields controlling this field's choices, including explicit and filter dependencies. Absent for non-contingent fields.", + "items": { + "type": "string" + } + }, + "possibleValueSourceName": { + "type": "string", + "description": "If this field's values should come from a possible value source, then that PVS is named here." + }, + "supplementalMetaData": { + "type": "object", + "description": "Additional frontend-visible metadata for this field, keyed by supplemental type." + }, + "type": { + "type": "string", + "description": "Data-type for this field" + }, + "validation": { + "type": "object", + "description": "The field's validation rules, as the server enforces them on insert and update (required, maxLength and tooLongBehavior, min/max value, pattern). Absent when the field has none. Since 1.6.0.", + "properties": { + "maxInclusive": { + "type": "boolean", + "description": "Whether maxValue itself is accepted (false: the value must be less).", + "nullable": true + }, + "maxLength": { + "type": "number", + "description": "For string fields, the most characters the field stores. What happens to a longer value is tooLongBehavior." + }, + "maxValue": { + "type": "string", + "description": "For number fields, the largest value accepted (plain digits, exact). See maxInclusive." + }, + "minInclusive": { + "type": "boolean", + "description": "Whether minValue itself is accepted (false: the value must be greater).", + "nullable": true + }, + "minValue": { + "type": "string", + "description": "For number fields, the smallest value accepted (plain digits, exact). See minInclusive." + }, + "pattern": { + "type": "string", + "description": "A regular expression a non-empty value must match as a whole (written to mean the same in Java and ECMAScript)." + }, + "patternMessage": { + "type": "string", + "description": "The message the server gives for a value that does not match pattern." + }, + "required": { + "type": "boolean", + "description": "True when a value is required.", + "nullable": true + }, + "tooLongBehavior": { + "type": "string", + "description": "With maxLength: ERROR (a longer value is refused), TRUNCATE or TRUNCATE_ELLIPSIS (it is trimmed on save), PASS_THROUGH (neither)." + } + } + } + } + }, + "hideSoftKeyboard": { + "type": "boolean", + "description": "Indicate if the frontend uses a software/on-screen keyboard, if the application should try to hide it (e.g., upon auto-focus).", + "nullable": true + }, + "placeholder": { + "type": "string", + "description": "Optional placeholder text to display in the input box." + }, + "submitOnEnter": { + "type": "boolean", + "description": "Indicate whether the form that this field is on should be submitted when Enter is pressed", + "nullable": true + } + } + }, + { + "type": "object", + "description": "Values used for a TEXT type widget block", + "properties": { + "endIcon": { + "type": "object", + "description": "An optional icon to display after the text", + "properties": { + "color": { + "type": "string", + "description": "A color code to use for displaying the icon" + }, + "name": { + "type": "string", + "description": "Material UI icon name (web); prefer semanticName" + }, + "path": { + "type": "string", + "description": "A path to an image file that can be requested from the server, to serve as the icon image instead of a material UI icon." + }, + "semanticName": { + "type": "string", + "description": "Client-neutral kebab-case icon token; null when unmapped." + } + } + }, + "startIcon": { + "type": "object", + "description": "An optional icon to display before the text", + "properties": { + "color": { + "type": "string", + "description": "A color code to use for displaying the icon" + }, + "name": { + "type": "string", + "description": "Material UI icon name (web); prefer semanticName" + }, + "path": { + "type": "string", + "description": "A path to an image file that can be requested from the server, to serve as the icon image instead of a material UI icon." + }, + "semanticName": { + "type": "string", + "description": "Client-neutral kebab-case icon token; null when unmapped." + } + } + }, + "text": { + "type": "string", + "description": "The text to display in the block" + } + } + } + ], + "$ref": "#/components/schemas/WidgetBlockValues" + } + } + }, + "WidgetBlockAudioValues": { + "type": "object", + "description": "Values used for an AUDIO type widget block", + "properties": { + "autoPlay": { + "type": "boolean", + "description": "Control if the file should automatically play when the block is rendered", + "nullable": true + }, + "path": { + "type": "string", + "description": "The path to the audio file on the server" + }, + "showControls": { + "type": "boolean", + "description": "Control if on-screen controls should be shown to allow the user to control playback", + "nullable": true + } + } + }, + "WidgetBlockBaseStyles": { + "type": "object", + "properties": { + "backgroundColor": { + "type": "string", + "description": "A background color to use for the block" + }, + "padding": { + "type": "object", + "description": "Optional padding to apply to the block", + "properties": { + "bottom": { + "type": "object" + }, + "left": { + "type": "object" + }, + "right": { + "type": "object" + }, + "top": { + "type": "object" + } + } + } + } + }, + "WidgetBlockButtonStyles": { + "type": "object", + "properties": { + "color": { + "type": "string", + "description": "A Color to use for the button. May be specified as a StandardColor (one of: SUCCESS, WARNING, ERROR, INFO, MUTED) or an RGB code." + }, + "format": { + "type": "string", + "description": "An optional indicator of the screen format preferred by the application to be used for this block, such as OUTLINED, FILLED, or TEXT. Different frontends may support different formats, and implement them differently." + } + } + }, + "WidgetBlockButtonValues": { + "type": "object", + "description": "Values used for a BUTTON type widget block", + "properties": { + "actionCode": { + "type": "string", + "description": "Code used within the app as the value submitted when the button is clicked" + }, + "controlCode": { + "type": "string", + "description": "Instructions for what should happen in the frontend (e.g., within a screen), when the button is clicked.\n\nTo show a modal composite block, use format: `showModal:${blockId}` (e.g., `showModal:myBlock`)\n\nTo hide a modal composite block, use format: `hideModal:${blockId}` (e.g., `hideModal:myBlock`)\n\nTo toggle visibility of a modal composite block, use format: `toggleModal:${blockId}` (e.g., `toggleModal:myBlock`)\n" + }, + "endIcon": { + "description": "An optional icon to display after the text in the button", + "$ref": "#/components/schemas/Icon" + }, + "label": { + "type": "string", + "description": "User-facing label to display in the button" + }, + "startIcon": { + "description": "An optional icon to display before the text in the button", + "$ref": "#/components/schemas/Icon" + } + } + }, + "WidgetBlockImageStyles": { + "type": "object", + "properties": { + "height": { + "type": "string", + "description": "A request to render the image at a specified height." + }, + "padding": { + "type": "object", + "description": "Optional padding to apply to the image", + "properties": { + "bottom": { + "type": "object" + }, + "left": { + "type": "object" + }, + "right": { + "type": "object" + }, + "top": { + "type": "object" + } + } + }, + "width": { + "type": "string", + "description": "A request to render the image at a specified width." + } + } + }, + "WidgetBlockImageValues": { + "type": "object", + "description": "Values used for an IMAGE type widget block", + "properties": { + "path": { + "type": "string", + "description": "The path to the image on the server" + } + } + }, + "WidgetBlockInputFieldValues": { + "type": "object", + "description": "Values used for an INPUT_FIELD type widget block", + "properties": { + "autoFocus": { + "type": "boolean", + "description": "Indicate whether this field should auto-focus when it is rendered", + "nullable": true + }, + "fieldMetaData": { + "description": "Metadata to define the field that this block controls", + "$ref": "#/components/schemas/FieldMetaData" + }, + "hideSoftKeyboard": { + "type": "boolean", + "description": "Indicate if the frontend uses a software/on-screen keyboard, if the application should try to hide it (e.g., upon auto-focus).", + "nullable": true + }, + "placeholder": { + "type": "string", + "description": "Optional placeholder text to display in the input box." + }, + "submitOnEnter": { + "type": "boolean", + "description": "Indicate whether the form that this field is on should be submitted when Enter is pressed", + "nullable": true + } + } + }, + "WidgetBlockStyles": { + "type": "object" + }, + "WidgetBlockTextStyles": { + "type": "object", + "properties": { + "color": { + "type": "string", + "description": "A Color to display the text in. May be specified as a StandardColor (one of: SUCCESS, WARNING, ERROR, INFO, MUTED) or an RGB code." + }, + "format": { + "type": "string", + "description": "An optional indicator of the screen format preferred by the application to be used for this block. Different frontends may support different formats, and implement them differently." + }, + "size": { + "type": "string", + "description": "An optional indicator of the size at which the text should be rendered. May be a named value (one oflargest, headline, title, body, smallest) or a numeric size - both are up to the frontend to interpret." + }, + "weight": { + "type": "string", + "description": "An optional indicator of the weight at which the text should be rendered. May be a named value (one ofextralight, thin, medium, black, semibold, bold, extrabold) or a numeric, e.g., 100, 200, ..., 900" + } + } + }, + "WidgetBlockTextValues": { + "type": "object", + "description": "Values used for a TEXT type widget block", + "properties": { + "endIcon": { + "description": "An optional icon to display after the text", + "$ref": "#/components/schemas/Icon" + }, + "startIcon": { + "description": "An optional icon to display before the text", + "$ref": "#/components/schemas/Icon" + }, + "text": { + "type": "string", + "description": "The text to display in the block" + } + } + }, + "WidgetBlockValues": { + "type": "object" + }, + "WidgetData": { + "description": "The data of a widget: one of the per-type shapes, chosen by `type` (the widget type). Clients render by type and ignore unknown properties; an unknown type is rendered as the widget label with its footerHTML/label only.", + "oneOf": [ + { + "$ref": "#/components/schemas/WidgetDataAlert" + }, + { + "$ref": "#/components/schemas/WidgetDataChart" + }, + { + "$ref": "#/components/schemas/WidgetDataLineChart" + }, + { + "$ref": "#/components/schemas/WidgetDataPieChart" + }, + { + "$ref": "#/components/schemas/WidgetDataChildRecordList" + }, + { + "$ref": "#/components/schemas/WidgetDataComposite" + }, + { + "$ref": "#/components/schemas/WidgetDataCronUI" + }, + { + "$ref": "#/components/schemas/WidgetDataDivider" + }, + { + "$ref": "#/components/schemas/WidgetDataDynamicForm" + }, + { + "$ref": "#/components/schemas/WidgetDataFieldValueList" + }, + { + "$ref": "#/components/schemas/WidgetDataFilterAndColumnsSetup" + }, + { + "$ref": "#/components/schemas/WidgetDataLocation" + }, + { + "$ref": "#/components/schemas/WidgetDataMultiStatistics" + }, + { + "$ref": "#/components/schemas/WidgetDataMultiTable" + }, + { + "$ref": "#/components/schemas/WidgetDataParent" + }, + { + "$ref": "#/components/schemas/WidgetDataProcess" + }, + { + "$ref": "#/components/schemas/WidgetDataQuickSightChart" + }, + { + "$ref": "#/components/schemas/WidgetDataRawHTML" + }, + { + "$ref": "#/components/schemas/WidgetDataRowBuilder" + }, + { + "$ref": "#/components/schemas/WidgetDataStatistics" + }, + { + "$ref": "#/components/schemas/WidgetDataStepper" + }, + { + "$ref": "#/components/schemas/WidgetDataTable" + }, + { + "$ref": "#/components/schemas/WidgetDataUSMap" + }, + { + "$ref": "#/components/schemas/WidgetDataGeneric" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "alert": "#/components/schemas/WidgetDataAlert", + "barChart": "#/components/schemas/WidgetDataChart", + "chart": "#/components/schemas/WidgetDataChart", + "childRecordList": "#/components/schemas/WidgetDataChildRecordList", + "composite": "#/components/schemas/WidgetDataComposite", + "cronUI": "#/components/schemas/WidgetDataCronUI", + "customComponent": "#/components/schemas/WidgetDataGeneric", + "dataBagViewer": "#/components/schemas/WidgetDataGeneric", + "divider": "#/components/schemas/WidgetDataDivider", + "dynamicForm": "#/components/schemas/WidgetDataDynamicForm", + "fieldValueList": "#/components/schemas/WidgetDataFieldValueList", + "filterAndColumnsSetup": "#/components/schemas/WidgetDataFilterAndColumnsSetup", + "generic": "#/components/schemas/WidgetDataGeneric", + "horizontalBarChart": "#/components/schemas/WidgetDataChart", + "html": "#/components/schemas/WidgetDataRawHTML", + "lineChart": "#/components/schemas/WidgetDataLineChart", + "location": "#/components/schemas/WidgetDataLocation", + "multiStatistics": "#/components/schemas/WidgetDataMultiStatistics", + "multiTable": "#/components/schemas/WidgetDataMultiTable", + "parentWidget": "#/components/schemas/WidgetDataParent", + "pieChart": "#/components/schemas/WidgetDataPieChart", + "pivotTableSetup": "#/components/schemas/WidgetDataGeneric", + "process": "#/components/schemas/WidgetDataProcess", + "quickSightChart": "#/components/schemas/WidgetDataQuickSightChart", + "rowBuilder": "#/components/schemas/WidgetDataRowBuilder", + "scriptViewer": "#/components/schemas/WidgetDataGeneric", + "smallLineChart": "#/components/schemas/WidgetDataLineChart", + "stackedBarChart": "#/components/schemas/WidgetDataChart", + "statistics": "#/components/schemas/WidgetDataStatistics", + "stepper": "#/components/schemas/WidgetDataStepper", + "table": "#/components/schemas/WidgetDataTable", + "usaMap": "#/components/schemas/WidgetDataUSMap" + } + } + }, + "WidgetDataAlert": { + "type": "object", + "description": "Data of alert widgets.", + "properties": { + "alertType": { + "type": "string", + "nullable": true, + "enum": [ + "ERROR", + "SUCCESS", + "WARNING" + ] + }, + "bulletList": { + "type": "array" + }, + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "hideWidget": { + "type": "boolean", + "nullable": true + }, + "html": { + "type": "string", + "nullable": true + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "text": { + "type": "string", + "description": "Plain text equivalent of html, preserving link text and line breaks." + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "alert" + ] + } + } + }, + "WidgetDataChart": { + "type": "object", + "description": "Data of chart, barChart, horizontalBarChart, and stackedBarChart widgets.", + "properties": { + "chartData": { + "type": "object", + "properties": { + "datasets": { + "type": "array", + "items": { + "type": "object", + "properties": { + "backgroundColor": { + "type": "string" + }, + "backgroundColors": { + "type": "array", + "description": "Colors per data point.", + "items": { + "type": "string" + } + }, + "color": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "type": "number", + "nullable": true + } + }, + "label": { + "type": "string" + }, + "urls": { + "type": "array", + "description": "Links per data point.", + "items": { + "type": "string" + } + } + } + } + }, + "labels": { + "type": "array", + "description": "Labels per data point.", + "items": { + "type": "string" + } + }, + "lineLabels": { + "type": "array", + "description": "Labels of the lines.", + "items": { + "type": "string" + } + }, + "urls": { + "type": "array", + "description": "Links per data point.", + "items": { + "type": "string" + } + } + } + }, + "chartSubheaderData": { + "type": "object", + "properties": { + "isGoodVsPrevious": { + "type": "boolean", + "nullable": true + }, + "isUpVsPrevious": { + "type": "boolean", + "nullable": true + }, + "mainNumber": { + "type": "number" + }, + "mainNumberUrl": { + "type": "string" + }, + "previousNumberUrl": { + "type": "string" + }, + "vsDescription": { + "type": "string" + }, + "vsPreviousNumber": { + "type": "number" + }, + "vsPreviousPercent": { + "type": "number" + } + } + }, + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "description": { + "type": "string", + "nullable": true + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "height": { + "type": "integer" + }, + "isCurrency": { + "type": "boolean" + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "title": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "chart", + "barChart", + "horizontalBarChart", + "stackedBarChart" + ] + } + } + }, + "WidgetDataChildRecordList": { + "type": "object", + "description": "Data of childRecordList widgets.", + "properties": { + "allowRecordDelete": { + "type": "boolean", + "nullable": true + }, + "allowRecordEdit": { + "type": "boolean", + "nullable": true + }, + "canAddChildRecord": { + "type": "boolean" + }, + "childFrontendTableMetaData": { + "type": "object", + "$ref": "#/components/schemas/TableMetaData" + }, + "childTableMetaData": { + "type": "object", + "$ref": "#/components/schemas/TableMetaData" + }, + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "defaultValuesForNewChildRecords": { + "type": "object" + }, + "defaultValuesForNewChildRecordsFromParentFields": { + "type": "object" + }, + "disableRowClick": { + "type": "boolean", + "nullable": true + }, + "disabledFieldsForNewChildRecords": { + "type": "array", + "description": "Fields disabled when adding a child record.", + "items": { + "type": "string" + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "includeExposedJoinTables": { + "type": "array" + }, + "isInProcess": { + "type": "boolean", + "nullable": true + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "omitFieldNames": { + "type": "array" + }, + "onlyIncludeFieldNames": { + "type": "array" + }, + "queryOutput": { + "type": "object", + "properties": { + "records": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OutputRecord" + } + } + } + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "tableName": { + "type": "string", + "nullable": true + }, + "tablePath": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "totalRows": { + "type": "number", + "nullable": true + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "childRecordList" + ] + }, + "viewAllLink": { + "type": "string", + "nullable": true + } + } + }, + "WidgetDataComposite": { + "type": "object", + "description": "Data of composite widgets.", + "properties": { + "blockId": { + "type": "string", + "nullable": true + }, + "blocks": { + "type": "array" + }, + "conditional": { + "type": "string", + "nullable": true + }, + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "layout": { + "type": "string", + "nullable": true, + "enum": [ + "FLEX_COLUMN", + "FLEX_ROW", + "FLEX_ROW_WRAPPED", + "FLEX_ROW_SPACE_BETWEEN", + "FLEX_ROW_CENTER", + "TABLE_SUB_ROW_DETAILS", + "BADGES_WRAPPER" + ] + }, + "link": { + "type": "object", + "properties": { + "href": { + "type": "string" + } + } + }, + "linkMap": { + "type": "object" + }, + "modalMode": { + "type": "string", + "nullable": true, + "enum": [ + "MODAL" + ] + }, + "overlayHtml": { + "type": "string", + "nullable": true + }, + "overlayStyleOverrides": { + "type": "object" + }, + "overlayText": { + "type": "string", + "description": "Plain text equivalent of overlayHtml, preserving link text and line breaks." + }, + "styleOverrides": { + "type": "object" + }, + "styles": { + "type": "object", + "properties": { + "backgroundColor": { + "type": "string", + "nullable": true + }, + "padding": { + "type": "object", + "properties": { + "bottom": { + "type": "string", + "nullable": true + }, + "left": { + "type": "string", + "nullable": true + }, + "right": { + "type": "string", + "nullable": true + }, + "top": { + "type": "string", + "nullable": true + } + } + } + } + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "tooltip": { + "type": "object", + "properties": { + "blockData": { + "type": "object", + "properties": { + "blocks": { + "type": "array" + }, + "layout": { + "type": "string", + "enum": [ + "FLEX_COLUMN", + "FLEX_ROW", + "FLEX_ROW_WRAPPED", + "FLEX_ROW_SPACE_BETWEEN", + "FLEX_ROW_CENTER", + "TABLE_SUB_ROW_DETAILS", + "BADGES_WRAPPER" + ] + }, + "modalMode": { + "type": "string", + "enum": [ + "MODAL" + ] + }, + "overlayHtml": { + "type": "string" + }, + "overlayStyleOverrides": { + "type": "object" + }, + "styleOverrides": { + "type": "object" + } + } + }, + "placement": { + "type": "string", + "enum": [ + "BOTTOM", + "LEFT", + "RIGHT", + "TOP" + ] + }, + "title": { + "type": "string" + } + } + }, + "tooltipMap": { + "type": "object" + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "composite" + ] + }, + "values": { + "type": "object", + "description": "Composite BaseValues has no predefined members." + } + } + }, + "WidgetDataCronUI": { + "type": "object", + "description": "Data of cronUI widgets.", + "properties": { + "cronDescription": { + "type": "string", + "nullable": true + }, + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "error": { + "type": "string", + "nullable": true + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "cronUI" + ] + } + } + }, + "WidgetDataDivider": { + "type": "object", + "description": "Data of divider widgets.", + "properties": { + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "divider" + ] + } + } + }, + "WidgetDataDynamicForm": { + "type": "object", + "description": "Data of dynamicForm widgets.", + "properties": { + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "fieldList": { + "type": "array" + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "mergedDynamicFormValuesIntoFieldName": { + "type": "string", + "nullable": true + }, + "noFieldsMessage": { + "type": "string", + "nullable": true + }, + "recordOfFieldValues": { + "type": "object", + "$ref": "#/components/schemas/OutputRecord" + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "dynamicForm" + ] + } + } + }, + "WidgetDataFieldValueList": { + "type": "object", + "description": "Data of fieldValueList widgets.", + "properties": { + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "fieldIndentLevels": { + "type": "object" + }, + "fieldLabelPrefixIconColors": { + "type": "object" + }, + "fieldLabelPrefixIconNames": { + "type": "object" + }, + "fields": { + "type": "array" + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "record": { + "type": "object", + "$ref": "#/components/schemas/OutputRecord" + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "fieldValueList" + ] + } + } + }, + "WidgetDataFilterAndColumnsSetup": { + "type": "object", + "description": "Data of filterAndColumnsSetup widgets.", + "properties": { + "allowVariables": { + "type": "boolean", + "nullable": true + }, + "apiName": { + "type": "string", + "nullable": true + }, + "apiPath": { + "type": "string", + "nullable": true + }, + "apiVersion": { + "type": "string", + "nullable": true + }, + "columnFieldName": { + "type": "string", + "nullable": true + }, + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "editButtonLabel": { + "type": "string", + "nullable": true + }, + "filterDefaultFieldNameSourceFieldNames": { + "type": "object" + }, + "filterDefaultFieldNames": { + "type": "array" + }, + "filterFieldName": { + "type": "string", + "nullable": true + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "hideColumns": { + "type": "boolean", + "nullable": true + }, + "hidePreview": { + "type": "boolean", + "nullable": true + }, + "hideSortBy": { + "type": "boolean", + "nullable": true + }, + "isApiVersioned": { + "type": "boolean", + "nullable": true + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "modalHeader": { + "type": "string", + "nullable": true + }, + "omitExposedJoins": { + "type": "array" + }, + "overrideIsEditable": { + "type": "boolean", + "nullable": true + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "tableName": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "filterAndColumnsSetup" + ] + } + } + }, + "WidgetDataGeneric": { + "type": "object", + "description": "Data of widget types without a fixed shape (generic, customComponent, dataBagViewer, pivotTableSetup, and scriptViewer): the common properties plus widget-specific ones.", + "properties": { + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "footerText": { + "type": "string", + "description": "Plain-text footer, preserving link text and line breaks." + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "generic", + "customComponent", + "dataBagViewer", + "pivotTableSetup", + "scriptViewer" + ] + } + }, + "additionalProperties": true + }, + "WidgetDataLineChart": { + "type": "object", + "description": "Data of lineChart and smallLineChart widgets.", + "properties": { + "chartData": { + "type": "object", + "properties": { + "datasets": { + "type": "array", + "items": { + "type": "object", + "properties": { + "backgroundColor": { + "type": "string" + }, + "backgroundColors": { + "type": "array", + "description": "Colors per data point.", + "items": { + "type": "string" + } + }, + "color": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "type": "number", + "nullable": true + } + }, + "label": { + "type": "string" + }, + "urls": { + "type": "array", + "description": "Links per data point.", + "items": { + "type": "string" + } + } + } + } + }, + "labels": { + "type": "array", + "description": "Labels per data point.", + "items": { + "type": "string" + } + }, + "lineLabels": { + "type": "array", + "description": "Labels of the lines.", + "items": { + "type": "string" + } + }, + "urls": { + "type": "array", + "description": "Links per data point.", + "items": { + "type": "string" + } + } + } + }, + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "isYAxisCurrency": { + "type": "boolean" + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "title": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "lineChart", + "smallLineChart" + ] + } + } + }, + "WidgetDataLocation": { + "type": "object", + "description": "Data of location widgets.", + "properties": { + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "description": { + "type": "string", + "nullable": true + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "imageUrl": { + "type": "string", + "nullable": true + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "location": { + "type": "string", + "nullable": true + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "title": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "location" + ] + } + } + }, + "WidgetDataMultiStatistics": { + "type": "object", + "description": "Data of multiStatistics widgets.", + "properties": { + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "statisticsGroupData": { + "type": "array" + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "title": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "multiStatistics" + ] + } + } + }, + "WidgetDataMultiTable": { + "type": "object", + "description": "Data of multiTable widgets.", + "properties": { + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "tableDataList": { + "type": "array" + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "multiTable" + ] + } + } + }, + "WidgetDataParent": { + "type": "object", + "description": "Data of parentWidget widgets.", + "properties": { + "childWidgetNameList": { + "type": "array" + }, + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "isLabelPageTitle": { + "type": "boolean" + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "layoutType": { + "type": "string", + "nullable": true, + "enum": [ + "GRID", + "TABS" + ] + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "parentWidget" + ] + } + } + }, + "WidgetDataPieChart": { + "type": "object", + "description": "Data of pieChart widgets.", + "properties": { + "chartData": { + "type": "object", + "properties": { + "datasets": { + "type": "array", + "items": { + "type": "object", + "properties": { + "backgroundColor": { + "type": "string" + }, + "backgroundColors": { + "type": "array", + "description": "Colors per data point.", + "items": { + "type": "string" + } + }, + "color": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "type": "number", + "nullable": true + } + }, + "label": { + "type": "string" + }, + "urls": { + "type": "array", + "description": "Links per data point.", + "items": { + "type": "string" + } + } + } + } + }, + "labels": { + "type": "array", + "description": "Labels per data point.", + "items": { + "type": "string" + } + }, + "lineLabels": { + "type": "array", + "description": "Labels of the lines.", + "items": { + "type": "string" + } + }, + "urls": { + "type": "array", + "description": "Links per data point.", + "items": { + "type": "string" + } + } + } + }, + "chartSubheaderData": { + "type": "object", + "properties": { + "isGoodVsPrevious": { + "type": "boolean", + "nullable": true + }, + "isUpVsPrevious": { + "type": "boolean", + "nullable": true + }, + "mainNumber": { + "type": "number" + }, + "mainNumberUrl": { + "type": "string" + }, + "previousNumberUrl": { + "type": "string" + }, + "vsDescription": { + "type": "string" + }, + "vsPreviousNumber": { + "type": "number" + }, + "vsPreviousPercent": { + "type": "number" + } + } + }, + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "description": { + "type": "string", + "nullable": true + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "height": { + "type": "integer" + }, + "isCurrency": { + "type": "boolean" + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "title": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "pieChart" + ] + } + } + }, + "WidgetDataProcess": { + "type": "object", + "description": "Data of process widgets.", + "properties": { + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "defaultValues": { + "type": "object" + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "processMetaData": { + "type": "object", + "$ref": "#/components/schemas/ProcessMetaData" + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "process" + ] + } + } + }, + "WidgetDataQuickSightChart": { + "type": "object", + "description": "Data of quickSightChart widgets.", + "properties": { + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "name": { + "type": "string", + "nullable": true + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "quickSightChart" + ] + }, + "url": { + "type": "string", + "nullable": true + } + } + }, + "WidgetDataRawHTML": { + "type": "object", + "description": "Data of html widgets.", + "properties": { + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "html": { + "type": "string", + "nullable": true + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "text": { + "type": "string", + "description": "Plain text equivalent of html, preserving link text and line breaks." + }, + "title": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "html" + ] + } + } + }, + "WidgetDataRowBuilder": { + "type": "object", + "description": "Data of rowBuilder widgets.", + "properties": { + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "defaultValuesForNewRecords": { + "type": "object" + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "hiddenValues": { + "type": "object" + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "records": { + "type": "array" + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "rowBuilder" + ] + } + } + }, + "WidgetDataStatistics": { + "type": "object", + "description": "Data of statistics widgets.", + "properties": { + "count": { + "type": "number", + "description": "Numeric statistic displayed by this widget.", + "nullable": true + }, + "countContext": { + "type": "string", + "nullable": true + }, + "countFontSize": { + "type": "string", + "nullable": true + }, + "countURL": { + "type": "string", + "nullable": true + }, + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "increaseIsGood": { + "type": "boolean" + }, + "isCurrency": { + "type": "boolean" + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "percentageAmount": { + "type": "number", + "nullable": true + }, + "percentageLabel": { + "type": "string", + "nullable": true + }, + "percentageURL": { + "type": "string", + "nullable": true + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "statistics" + ] + } + } + }, + "WidgetDataStepper": { + "type": "object", + "description": "Data of stepper widgets.", + "properties": { + "activeStep": { + "type": "integer" + }, + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "steps": { + "type": "array" + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "title": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "stepper" + ] + } + } + }, + "WidgetDataTable": { + "type": "object", + "description": "Data of table widgets.", + "properties": { + "columns": { + "type": "array" + }, + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "fixedHeight": { + "type": "number", + "nullable": true + }, + "fixedStickyLastRow": { + "type": "boolean", + "nullable": true + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "hidePaginationDropdown": { + "type": "boolean", + "nullable": true + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "linkText": { + "type": "string", + "nullable": true + }, + "linkURL": { + "type": "string", + "nullable": true + }, + "noRowsFoundHTML": { + "type": "string", + "nullable": true + }, + "rows": { + "type": "array" + }, + "rowsPerPage": { + "type": "number", + "nullable": true + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "table" + ] + } + } + }, + "WidgetDataUSMap": { + "type": "object", + "description": "Data of usaMap widgets.", + "properties": { + "csvData": { + "type": "array", + "description": "Rows (each a list of cells) for exporting the widget as CSV.", + "items": { + "type": "array", + "items": {} + } + }, + "dropdownDataList": { + "type": "array", + "description": "Options of each dropdown filter: a list per dropdown of {id, label} objects.", + "items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "dropdownDefaultValueList": { + "type": "array", + "description": "Default value of each dropdown filter.", + "items": { + "type": "string" + } + }, + "dropdownLabelList": { + "type": "array", + "description": "Labels of the dropdown filters.", + "items": { + "type": "string" + } + }, + "dropdownNameList": { + "type": "array", + "description": "Names of the dropdown filters the widget offers (parallel to the other dropdown lists).", + "items": { + "type": "string" + } + }, + "dropdownNeedsSelectedText": { + "type": "string", + "description": "Message to show until every dropdown has a value." + }, + "footerHTML": { + "type": "string", + "description": "Footer, as HTML. Non-web clients render it as plain text." + }, + "footerText": { + "type": "string", + "description": "Plain text equivalent of footerHTML, preserving link text and line breaks." + }, + "hasPermission": { + "type": "boolean", + "description": "False when the user may not see this widget's data; show the label and a permission message only." + }, + "height": { + "type": "string", + "nullable": true + }, + "label": { + "type": "string", + "description": "Title of the widget (overrides the metadata label when present)." + }, + "mapMarkerList": { + "type": "array" + }, + "sublabel": { + "type": "string", + "description": "Secondary title." + }, + "type": { + "type": "string", + "description": "The widget type this data is for.", + "enum": [ + "usaMap" + ] + } + } + }, + "WidgetResponseV1": { + "type": "object", + "properties": { + "widgetData": { + "type": "object", + "description": "Widget data object, whose shape varies by widget type." + } + } + }, + "HealthCheckV1": { + "properties": { + "name": { + "nullable": true, + "type": "string" + }, + "label": { + "nullable": true, + "type": "string" + }, + "kind": { + "nullable": true, + "type": "string" + }, + "severity": { + "nullable": true, + "type": "string" + }, + "currentStatus": { + "nullable": true, + "type": "string" + }, + "currentMessage": { + "nullable": true, + "type": "string" + }, + "currentSince": { + "nullable": true, + "type": "string" + }, + "lastRunAt": { + "nullable": true, + "type": "string" + }, + "lastLatencyMs": { + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "HealthComponentV1": { + "properties": { + "name": { + "nullable": true, + "type": "string" + }, + "label": { + "nullable": true, + "type": "string" + }, + "status": { + "nullable": true, + "type": "string" + }, + "since": { + "nullable": true, + "type": "string" + }, + "checksUp": { + "nullable": true, + "type": "integer" + }, + "checksDegraded": { + "nullable": true, + "type": "integer" + }, + "checksDown": { + "nullable": true, + "type": "integer" + }, + "checksUnknown": { + "nullable": true, + "type": "integer" + }, + "worstCheckId": { + "nullable": true, + "type": "integer" + }, + "updatedAt": { + "nullable": true, + "type": "string" + }, + "checks": { + "items": { + "$ref": "#/components/schemas/HealthCheckV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "HealthCountsV1": { + "properties": { + "up": { + "nullable": true, + "type": "integer" + }, + "degraded": { + "nullable": true, + "type": "integer" + }, + "down": { + "nullable": true, + "type": "integer" + }, + "unknown": { + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "HealthDetailsV1": { + "properties": { + "values": { + "additionalProperties": true, + "type": "object" + } + }, + "type": "object" + }, + "HealthHistoryV1": { + "properties": { + "results": { + "items": { + "$ref": "#/components/schemas/HealthResultV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "HealthMetricV1": { + "properties": { + "name": { + "nullable": true, + "type": "string" + }, + "value": { + "type": "number" + }, + "unit": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "HealthResultV1": { + "properties": { + "id": { + "nullable": true, + "type": "integer" + }, + "status": { + "nullable": true, + "type": "string" + }, + "message": { + "nullable": true, + "type": "string" + }, + "detailsJson": { + "nullable": true, + "type": "string" + }, + "metricsJson": { + "nullable": true, + "type": "string" + }, + "latencyMs": { + "nullable": true, + "type": "integer" + }, + "startedAt": { + "nullable": true, + "type": "string" + }, + "finishedAt": { + "nullable": true, + "type": "string" + }, + "runnerPod": { + "nullable": true, + "type": "string" + }, + "isTransition": { + "type": "boolean" + }, + "triggeredBy": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "HealthRunV1": { + "properties": { + "status": { + "nullable": true, + "type": "string" + }, + "message": { + "nullable": true, + "type": "string" + }, + "details": { + "$ref": "#/components/schemas/HealthDetailsV1" + }, + "latencyMs": { + "nullable": true, + "type": "integer" + }, + "metrics": { + "items": { + "$ref": "#/components/schemas/HealthMetricV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "HealthRunnerV1": { + "properties": { + "lastBeatAt": { + "nullable": true, + "type": "string" + }, + "pods": { + "items": { + "nullable": true, + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "HealthSummaryV1": { + "properties": { + "status": { + "nullable": true, + "type": "string" + }, + "since": { + "nullable": true, + "type": "string" + }, + "counts": { + "$ref": "#/components/schemas/HealthCountsV1" + }, + "components": { + "items": { + "$ref": "#/components/schemas/HealthComponentV1" + }, + "type": "array" + }, + "runner": { + "$ref": "#/components/schemas/HealthRunnerV1" + } + }, + "type": "object" + }, + "AlertsActionV1": { + "description": "An available action: operationId targets an inbox operation with this item id; process actions provide a complete href.", + "properties": { + "href": { + "type": "string" + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "operationId": { + "type": "string" + }, + "processName": { + "type": "string" + } + }, + "type": "object" + }, + "AlertsErrorV1": { + "description": "Deprecated since 1.2.0: errors use BasicErrorResponseV1.", + "properties": { + "error": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "AlertsFollowV1": { + "description": "Capability discovery only. Next obtains the follow URL from its collaboration module.", + "properties": { + "available": { + "description": "True exactly when the collaboration UI API extension is registered.", + "type": "boolean" + } + }, + "type": "object" + }, + "AlertsInboxItemV1": { + "description": "A notification recipient. body is included only in page items and banners; alertId only for ALERT notifications.", + "properties": { + "actions": { + "items": { + "$ref": "#/components/schemas/AlertsActionV1" + }, + "type": "array" + }, + "age": { + "type": "string" + }, + "alertId": { + "nullable": true, + "type": "integer" + }, + "body": { + "nullable": true, + "type": "string" + }, + "category": { + "nullable": true, + "type": "string" + }, + "deliveredAt": { + "nullable": true, + "type": "string" + }, + "href": { + "description": "Existing safe link, or null.", + "nullable": true, + "type": "string" + }, + "id": { + "type": "integer" + }, + "linkLabel": { + "nullable": true, + "type": "string" + }, + "notificationId": { + "type": "integer" + }, + "severity": { + "nullable": true, + "type": "string" + }, + "source": { + "nullable": true, + "type": "string" + }, + "sticky": { + "type": "boolean" + }, + "title": { + "nullable": true, + "type": "string" + }, + "unread": { + "type": "boolean" + } + }, + "type": "object" + }, + "AlertsInboxPageV1": { + "description": "Filtered notification page.", + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/AlertsInboxItemV1" + }, + "type": "array" + }, + "limit": { + "type": "integer" + }, + "offset": { + "type": "integer" + }, + "total": { + "type": "integer" + } + }, + "type": "object" + }, + "AlertsInboxSummaryV1": { + "description": "Bell summary, latest ten items and up to three sticky banners.", + "properties": { + "alertsHref": { + "type": "string" + }, + "banners": { + "items": { + "$ref": "#/components/schemas/AlertsInboxItemV1" + }, + "type": "array" + }, + "highestUnreadSeverity": { + "nullable": true, + "type": "string" + }, + "inboxHref": { + "description": "Canonical inbox navigation link.", + "type": "string" + }, + "items": { + "items": { + "$ref": "#/components/schemas/AlertsInboxItemV1" + }, + "type": "array" + }, + "notificationsHref": { + "description": "Existing notifications page link; retained for compatibility.", + "type": "string" + }, + "pollSeconds": { + "type": "integer" + }, + "preferencesSection": { + "description": "Name of the user Preferences section for notification settings (/qqq/v1/preferences/{name}), or null when not registered.", + "nullable": true, + "type": "string" + }, + "unreadCount": { + "type": "integer" + } + }, + "type": "object" + }, + "AlertsInboxTargetV1": { + "description": "Select id, nonempty ids (first 500), legacy alertId, or all:true in that precedence. All scans are capped at 1000 rows.", + "properties": { + "alertId": { + "type": "integer" + }, + "all": { + "type": "boolean" + }, + "id": { + "type": "integer" + }, + "ids": { + "items": { + "type": "integer" + }, + "type": "array" + } + }, + "type": "object" + }, + "AlertsMutationResultV1": { + "description": "Number of the caller own recipient rows changed.", + "properties": { + "updated": { + "type": "integer" + } + }, + "type": "object" + }, + "AlertsPanelAlertV1": { + "description": "A visible open alert with permission-aware process actions.", + "properties": { + "actions": { + "items": { + "$ref": "#/components/schemas/AlertsActionV1" + }, + "type": "array" + }, + "age": { + "type": "string" + }, + "alertId": { + "type": "integer" + }, + "group": { + "nullable": true, + "type": "string" + }, + "href": { + "type": "string" + }, + "raisedAt": { + "nullable": true, + "type": "string" + }, + "severity": { + "nullable": true, + "type": "string" + }, + "status": { + "nullable": true, + "type": "string" + }, + "title": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "AlertsRecordPanelV1": { + "description": "Open alerts, recent resolutions and collaboration capability. watching is deprecated legacy subscription state.", + "properties": { + "canManage": { + "type": "boolean" + }, + "follow": { + "$ref": "#/components/schemas/AlertsFollowV1" + }, + "open": { + "items": { + "$ref": "#/components/schemas/AlertsPanelAlertV1" + }, + "type": "array" + }, + "openCount": { + "type": "integer" + }, + "resolvedLast30Days": { + "type": "integer" + }, + "viewAllHref": { + "nullable": true, + "type": "string" + }, + "visible": { + "type": "boolean" + }, + "watching": { + "description": "Deprecated: existing RECORD subscriptions only; does not represent collaboration follow state.", + "type": "boolean" + } + }, + "type": "object" + }, + "AlertsUnreadTargetV1": { + "description": "Select id or nonempty ids (first 500), in that precedence. Legacy alertId is also accepted for compatibility. all is not supported.", + "properties": { + "alertId": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "ids": { + "items": { + "type": "integer" + }, + "type": "array" + } + }, + "type": "object" + }, + "AssistantAccessResponseV1": { + "description": "Explain access: per table, the user's UI permissions, the assistant's data access, and each tool's verdict.", + "properties": { + "tables": { + "items": { + "additionalProperties": true, + "description": "table, label, dataAccess, dataAccessSource, ui {visible, read, insert, edit, delete}, operations [{tool, operation, allowed, reason}].", + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "AssistantActionV1": { + "description": "A write the assistant proposed and its state.", + "properties": { + "id": { + "type": "integer" + }, + "status": { + "description": "PENDING, RUNNING, EXECUTED, FAILED, REJECTED or EXPIRED.", + "type": "string" + }, + "toolName": { + "type": "string" + }, + "tableName": { + "type": "string" + }, + "recordId": { + "nullable": true, + "type": "string" + }, + "summary": { + "type": "string" + }, + "httpStatus": { + "description": "The UI API status of the write.", + "nullable": true, + "type": "integer" + }, + "resultSummary": { + "nullable": true, + "type": "string" + }, + "expiresAt": { + "nullable": true, + "type": "string" + }, + "outcome": { + "description": "After a confirm: the tool outcome.", + "nullable": true, + "type": "string" + }, + "message": { + "description": "After a confirm: what happened.", + "nullable": true, + "type": "string" + }, + "href": { + "description": "After a confirm: the written record's /app link.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "AssistantActiveTurnsResponseV1": { + "description": "The caller's active runs, newest first; stale leases are reaped.", + "properties": { + "turns": { + "items": { + "description": "An active assistant run.", + "properties": { + "turnId": { + "type": "integer" + }, + "conversationId": { + "type": "integer" + }, + "assistantMessageId": { + "type": "integer" + }, + "userMessageId": { + "type": "integer" + }, + "status": { + "description": "RUNNING or CANCELLING.", + "type": "string" + }, + "phase": { + "type": "string" + }, + "startedAt": { + "description": "ISO-8601.", + "type": "string" + }, + "heartbeatAt": { + "description": "ISO-8601.", + "type": "string" + }, + "elapsedMs": { + "type": "integer" + }, + "live": { + "description": "Running on this replica.", + "type": "boolean" + }, + "concurrencyMode": { + "description": "SUPERSEDE or CONCURRENT.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "AssistantClientErrorReportV1": { + "description": "An error the client hit while showing the assistant (since 1.5.0). scope and message are required; longer values are truncated, message and stacks are scrubbed of e-mail addresses, long numbers, tokens and query strings, and ids are kept only when they are the user's own.", + "properties": { + "scope": { + "description": "Required. Where it happened: assistant-panel, assistant-message, assistant-part, assistant-render, assistant-stream, widget, record-section, page...", + "maxLength": 64, + "type": "string" + }, + "message": { + "description": "Required. The error message.", + "maxLength": 500, + "type": "string" + }, + "errorName": { + "description": "The error's name, e.g. TypeError.", + "maxLength": 100, + "nullable": true, + "type": "string" + }, + "stack": { + "description": "The JavaScript stack.", + "maxLength": 4000, + "nullable": true, + "type": "string" + }, + "componentStack": { + "description": "The React component stack.", + "maxLength": 4000, + "nullable": true, + "type": "string" + }, + "requestId": { + "description": "The request or trace id the client saw.", + "maxLength": 128, + "nullable": true, + "type": "string" + }, + "route": { + "description": "The page path (no host, query or fragment).", + "maxLength": 300, + "nullable": true, + "type": "string" + }, + "conversationId": { + "nullable": true, + "type": "integer" + }, + "messageId": { + "nullable": true, + "type": "integer" + }, + "turnId": { + "nullable": true, + "type": "integer" + }, + "partType": { + "description": "The message part type being shown.", + "maxLength": 64, + "nullable": true, + "type": "string" + }, + "renderType": { + "description": "The render type being shown.", + "maxLength": 64, + "nullable": true, + "type": "string" + }, + "appVersion": { + "description": "The client build.", + "maxLength": 64, + "nullable": true, + "type": "string" + }, + "occurredAt": { + "description": "ISO-8601 instant.", + "format": "date-time", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "AssistantClientErrorResponseV1": { + "description": "Whether the report was stored: false when the user's reports are over the per-minute limit (still 202).", + "properties": { + "accepted": { + "type": "boolean" + } + }, + "type": "object" + }, + "AssistantConfigResponseV1": { + "description": "Whether the assistant is available to this user, and how.", + "properties": { + "enabled": { + "description": "Whether the panel may be used.", + "type": "boolean" + }, + "reason": { + "description": "Why not: DISABLED, NO_PERMISSION, NOT_CONFIGURED or KILL_SWITCH.", + "nullable": true, + "type": "string" + }, + "shortcut": { + "description": "Keyboard shortcut, e.g. mod+j.", + "type": "string" + }, + "model": { + "description": "The model that answers.", + "type": "string" + }, + "limits": { + "additionalProperties": true, + "description": "maxTurnSeconds and maxToolCallsPerTurn. When features.attachments is true also maxAttachmentBytes (the largest file read, in bytes), maxAttachments (files per question) and attachmentTypes (human-readable type names for the file picker hint; images only when the model reads them).", + "type": "object" + }, + "features": { + "additionalProperties": true, + "description": "writes: some table allows writes; pendingActions: writes wait for confirmation; attachments: files uploaded with POST /qqq/v1/uploads and sent as pageContext.attachments [{uploadRef, fileName}] are read for the question.", + "type": "object" + }, + "profile": { + "$ref": "#/components/schemas/AssistantProfileV1" + }, + "conversationsTable": { + "description": "Since 1.6.0: the table name of the user's conversations (assistant_conversation) for the standard table UI (manage, archive, restore and delete); present only when this session may query that table.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "AssistantConversationDetailResponseV1": { + "description": "A conversation and a page of its messages, oldest first.", + "properties": { + "conversation": { + "$ref": "#/components/schemas/AssistantConversationV1" + }, + "messages": { + "items": { + "$ref": "#/components/schemas/AssistantMessageV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "AssistantConversationListResponseV1": { + "description": "The user's conversations, newest first.", + "properties": { + "conversations": { + "items": { + "$ref": "#/components/schemas/AssistantConversationV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "AssistantConversationV1": { + "description": "One of the user's own conversations.", + "properties": { + "id": { + "type": "integer" + }, + "title": { + "nullable": true, + "type": "string" + }, + "status": { + "description": "ACTIVE or ARCHIVED.", + "type": "string" + }, + "pinned": { + "type": "boolean" + }, + "lastMessageAt": { + "description": "ISO-8601 instant.", + "nullable": true, + "type": "string" + }, + "unreadCount": { + "type": "integer" + }, + "createDate": { + "description": "ISO-8601 instant.", + "nullable": true, + "type": "string" + }, + "running": { + "description": "Since 1.6.0, in GET /conversations items only: whether an answer is in progress (a RUNNING or CANCELLING turn that is not orphaned).", + "nullable": true, + "type": "boolean" + } + }, + "type": "object" + }, + "AssistantErrorV1": { + "description": "Deprecated since 1.3.0: errors use BasicErrorResponseV1.", + "properties": { + "error": { + "description": "A message for the user.", + "type": "string" + }, + "code": { + "description": "BUDGET, RATE_LIMIT, NOT_CONFIGURED, KILL_SWITCH, DISABLED, NO_PERMISSION...", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "AssistantMessageV1": { + "description": "A message: the user's text or the assistant's reply as parts (text, tool, record_refs, navigate, notice).", + "properties": { + "id": { + "type": "integer" + }, + "role": { + "description": "USER or ASSISTANT.", + "type": "string" + }, + "status": { + "type": "string" + }, + "turnId": { + "nullable": true, + "type": "integer" + }, + "createDate": { + "nullable": true, + "type": "string" + }, + "parts": { + "items": { + "additionalProperties": true, + "description": "A message part.", + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "AssistantProfileV1": { + "description": "How the assistant presents itself (admin-configured; text only, it never changes access).", + "properties": { + "displayName": { + "description": "The assistant's name.", + "type": "string" + }, + "icon": { + "description": "A Material icon name.", + "type": "string" + }, + "greeting": { + "description": "Shown on a new conversation.", + "nullable": true, + "type": "string" + }, + "starterPrompts": { + "description": "Up to three suggested first questions in total: permitted configured questions first, then generated questions. Table, row and field access are checked on every request.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "AssistantRecordsRenderV1": { + "description": "A tool part's render of type records (query results). columns and rows are always present - empty when the query matched nothing (since 1.4.0; older stored parts are completed when read).", + "properties": { + "type": { + "description": "records", + "type": "string" + }, + "tableName": { + "type": "string" + }, + "tableLabel": { + "type": "string" + }, + "columns": { + "description": "Always present; empty when nothing matched.", + "items": { + "description": "A column.", + "properties": { + "name": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "rows": { + "description": "Always present; empty when nothing matched.", + "items": { + "description": "A row.", + "properties": { + "id": { + "description": "The primary key.", + "type": "string" + }, + "href": { + "description": "The record's /app link.", + "type": "string" + }, + "values": { + "additionalProperties": true, + "description": "Display values by column name.", + "type": "object" + } + }, + "type": "object" + }, + "type": "array" + }, + "totalCount": { + "description": "All matching rows.", + "nullable": true, + "type": "integer" + }, + "truncated": { + "description": "More rows match than are shown.", + "type": "boolean" + }, + "openHref": { + "description": "The Query screen link.", + "type": "string" + } + }, + "type": "object" + }, + "AssistantStatusResponseV1": { + "description": "An acknowledgement.", + "properties": { + "status": { + "type": "string" + } + }, + "type": "object" + }, + "AssistantTurnEventV1": { + "description": "One server-sent event of a turn (event: , id: , data: this object). Types: message.start, turn.phase, text.delta, tool.start, tool.result, ui.navigate, notice, usage, message.end, error, ping.", + "properties": { + "seq": { + "description": "Sequence number; resume with ?after=.", + "type": "integer" + }, + "type": { + "description": "The event type (also the SSE event name).", + "type": "string" + }, + "data": { + "additionalProperties": true, + "description": "The event's fields, by type. message.start includes startedAt (ISO-8601). turn.phase includes phase (thinking, tool, writing), optional toolName and label.", + "type": "object" + } + }, + "type": "object" + }, + "CollaborationAccessRequestCreateRequestV1": { + "properties": { + "message": { + "description": "message.", + "nullable": true, + "type": "string" + }, + "recordId": { + "description": "recordId.", + "nullable": true, + "type": "string" + }, + "shareId": { + "description": "shareId.", + "nullable": true, + "type": "integer" + }, + "tableName": { + "description": "tableName.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationAccessRequestListV1": { + "properties": { + "items": { + "description": "items.", + "items": { + "$ref": "#/components/schemas/CollaborationAccessRequestV1" + }, + "nullable": true, + "type": "array" + }, + "nextCursor": { + "description": "nextCursor.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationAccessRequestV1": { + "properties": { + "handledAt": { + "description": "handledAt.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "handledByDisplayName": { + "description": "Display name of the person who handled the request.", + "nullable": true, + "type": "string" + }, + "id": { + "description": "id.", + "nullable": true, + "type": "integer" + }, + "message": { + "description": "message.", + "nullable": true, + "type": "string" + }, + "note": { + "description": "note.", + "nullable": true, + "type": "string" + }, + "recordId": { + "description": "recordId.", + "nullable": true, + "type": "string" + }, + "requesterDisplayName": { + "description": "Requester display name.", + "nullable": true, + "type": "string" + }, + "requesterUserId": { + "description": "requesterUserId.", + "nullable": true, + "type": "string" + }, + "status": { + "description": "status.", + "nullable": true, + "type": "string" + }, + "tableName": { + "description": "tableName.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationAssignmentRequestV1": { + "properties": { + "assigneeUserId": { + "description": "assigneeUserId.", + "nullable": true, + "type": "string" + }, + "ownerUserId": { + "description": "ownerUserId.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationAssignmentV1": { + "properties": { + "assigneeDisplayName": { + "description": "Assignee display name.", + "nullable": true, + "type": "string" + }, + "assigneeUserId": { + "description": "assigneeUserId.", + "nullable": true, + "type": "string" + }, + "id": { + "description": "id.", + "nullable": true, + "type": "integer" + }, + "ownerDisplayName": { + "description": "Owner display name.", + "nullable": true, + "type": "string" + }, + "ownerUserId": { + "description": "ownerUserId.", + "nullable": true, + "type": "string" + }, + "recordId": { + "description": "recordId.", + "nullable": true, + "type": "string" + }, + "tableName": { + "description": "tableName.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationAttachmentListV1": { + "description": "Attachments, newest first.", + "properties": { + "items": { + "description": "Attachments, newest first.", + "items": { + "$ref": "#/components/schemas/CollaborationAttachmentV1" + }, + "nullable": true, + "type": "array" + }, + "nextCursor": { + "description": "Opaque continuation token; null when finished or the service has no continuation support.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationAttachmentPatchRequestV1": { + "description": "Change attachment display metadata.", + "properties": { + "description": { + "description": "Optional description; empty clears, null leaves unchanged.", + "nullable": true, + "type": "string" + }, + "fileName": { + "description": "Optional new display filename; null leaves unchanged.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationAttachmentUploadRequestV1": { + "description": "Multipart upload with exactly one file part named file.", + "properties": { + "description": { + "description": "Optional description.", + "nullable": true, + "type": "string" + }, + "file": { + "description": "Required file content.", + "format": "binary", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationAttachmentV1": { + "description": "An attachment visible through its parent record; no storage coordinates are exposed.", + "properties": { + "canDelete": { + "description": "Whether the caller may change or delete this attachment.", + "nullable": true, + "type": "boolean" + }, + "contentType": { + "description": "MIME content type.", + "nullable": true, + "type": "string" + }, + "createDate": { + "description": "Upload time.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "createdByDisplayName": { + "description": "Uploader display name.", + "nullable": true, + "type": "string" + }, + "createdByUserId": { + "description": "Uploader identity.", + "nullable": true, + "type": "string" + }, + "description": { + "description": "Optional description.", + "nullable": true, + "type": "string" + }, + "fileName": { + "description": "Safe display filename.", + "nullable": true, + "type": "string" + }, + "id": { + "description": "Attachment identifier.", + "nullable": true, + "type": "integer" + }, + "recordId": { + "description": "Canonical parent record key.", + "nullable": true, + "type": "string" + }, + "sha256": { + "description": "SHA-256 content digest.", + "nullable": true, + "type": "string" + }, + "sizeBytes": { + "description": "Stored byte count.", + "nullable": true, + "type": "integer" + }, + "tableName": { + "description": "Parent table metadata name.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationCommentEditRequestV1": { + "description": "Replace the caller's comment body.", + "properties": { + "body": { + "description": "Required replacement body, 1 to 20000 characters.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationCommentHistoryV1": { + "description": "Previous bodies in edit order.", + "properties": { + "items": { + "description": "Previous bodies in edit order.", + "items": { + "$ref": "#/components/schemas/CollaborationCommentRevisionV1" + }, + "nullable": true, + "type": "array" + }, + "nextCursor": { + "description": "Opaque continuation token; null when finished or the service has no continuation support.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationCommentPageV1": { + "description": "Root threads by latest activity, with replies.", + "properties": { + "nextCursor": { + "description": "Opaque continuation token; null when finished or the service has no continuation support.", + "nullable": true, + "type": "string" + }, + "threads": { + "description": "Root threads by latest activity, with replies.", + "items": { + "$ref": "#/components/schemas/CollaborationCommentV1" + }, + "nullable": true, + "type": "array" + } + }, + "type": "object" + }, + "CollaborationCommentPostRequestV1": { + "description": "Post a root comment or one-level reply.", + "properties": { + "body": { + "description": "Required body, 1 to 20000 characters; mentions use @[Name](user:id).", + "nullable": true, + "type": "string" + }, + "fieldName": { + "description": "Optional existing parent field name.", + "nullable": true, + "type": "string" + }, + "parentCommentId": { + "description": "Optional comment to reply to.", + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "CollaborationCommentRevisionV1": { + "description": "A previous comment body.", + "properties": { + "body": { + "description": "Previous body text.", + "nullable": true, + "type": "string" + }, + "editedAt": { + "description": "Time the body was replaced.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "editedByDisplayName": { + "description": "Editor display name.", + "nullable": true, + "type": "string" + }, + "editedByUserId": { + "description": "Editor identity.", + "nullable": true, + "type": "string" + }, + "id": { + "description": "Revision identifier.", + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "CollaborationCommentV1": { + "description": "A comment or reply; deleted comments retain their position without body text.", + "properties": { + "authorDisplayName": { + "description": "Author display name.", + "nullable": true, + "type": "string" + }, + "authorUserId": { + "description": "Author identity.", + "nullable": true, + "type": "string" + }, + "body": { + "description": "Plain text with mention tokens; null for deleted comments.", + "nullable": true, + "type": "string" + }, + "canDelete": { + "description": "Caller may delete this comment.", + "nullable": true, + "type": "boolean" + }, + "canEdit": { + "description": "Caller may edit the body.", + "nullable": true, + "type": "boolean" + }, + "createdAt": { + "description": "Creation time.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "deleted": { + "description": "Whether the comment is soft deleted.", + "nullable": true, + "type": "boolean" + }, + "editedAt": { + "description": "Last edit time, if edited.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "fieldName": { + "description": "Optional field being discussed.", + "nullable": true, + "type": "string" + }, + "id": { + "description": "Comment identifier.", + "nullable": true, + "type": "integer" + }, + "mentions": { + "description": "Mention recipients.", + "items": { + "$ref": "#/components/schemas/CollaborationMentionV1" + }, + "nullable": true, + "type": "array" + }, + "parentCommentId": { + "description": "Root comment for a reply; null on roots.", + "nullable": true, + "type": "integer" + }, + "replies": { + "description": "Replies in oldest-first order; empty on replies.", + "items": { + "$ref": "#/components/schemas/CollaborationCommentV1" + }, + "nullable": true, + "type": "array" + }, + "resolved": { + "description": "Whether the thread is resolved.", + "nullable": true, + "type": "boolean" + }, + "threadId": { + "description": "Root thread identifier; null on roots.", + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "CollaborationDownloadV1": { + "description": "Temporary access to file bytes. Clients follow url.", + "properties": { + "url": { + "description": "Presigned URL, valid for five minutes. Clients follow url; never persist it.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationErrorV1": { + "description": "Deprecated since 1.1.0: errors use BasicErrorResponseV1.", + "properties": { + "error": { + "description": "Human-readable reason the operation failed.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationFavoriteListV1": { + "description": "Ordered personal favorites.", + "properties": { + "items": { + "description": "Ordered personal favorites.", + "items": { + "$ref": "#/components/schemas/CollaborationFavoriteV1" + }, + "nullable": true, + "type": "array" + }, + "nextCursor": { + "description": "Opaque continuation token; null when finished or the service has no continuation support.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationFavoriteOrderRequestV1": { + "description": "Move selected favorites first and optionally assign folders.", + "properties": { + "folders": { + "additionalProperties": { + "nullable": true, + "type": "string" + }, + "description": "Optional map from favorite identifier to folder; null values clear folders.", + "nullable": true, + "type": "object" + }, + "ids": { + "description": "Required ordered favorite identifiers, with no duplicates.", + "items": { + "type": "integer" + }, + "nullable": true, + "type": "array" + } + }, + "type": "object" + }, + "CollaborationFavoriteV1": { + "description": "A saved navigation target, with availability rechecked for the caller.", + "properties": { + "available": { + "description": "Whether the caller can currently open this target.", + "nullable": true, + "type": "boolean" + }, + "folder": { + "description": "Optional personal grouping.", + "nullable": true, + "type": "string" + }, + "href": { + "description": "Navigation link, absent for unavailable targets.", + "nullable": true, + "type": "string" + }, + "id": { + "description": "Favorite identifier.", + "nullable": true, + "type": "integer" + }, + "label": { + "description": "Current display label; Unavailable when access is lost.", + "nullable": true, + "type": "string" + }, + "recordId": { + "description": "Canonical record key; null for non-record targets.", + "nullable": true, + "type": "string" + }, + "sortOrder": { + "description": "Position in the personal list.", + "nullable": true, + "type": "integer" + }, + "targetName": { + "description": "Metadata name of the table, app, process, report or saved view.", + "nullable": true, + "type": "string" + }, + "targetType": { + "description": "Kind of navigation target.", + "enum": [ + "TABLE", + "APP", + "RECORD", + "PROCESS", + "REPORT", + "SAVED_VIEW" + ], + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationFollowRequestV1": { + "description": "Configure the caller's follow preferences.", + "properties": { + "notifyOnChange": { + "description": "Optional change notifications preference; omission retains current setting.", + "nullable": true, + "type": "boolean" + }, + "notifyOnComment": { + "description": "Optional comment notifications preference; omission retains current setting.", + "nullable": true, + "type": "boolean" + } + }, + "type": "object" + }, + "CollaborationFollowStateV1": { + "description": "The current caller's subscription state.", + "properties": { + "follow": { + "$ref": "#/components/schemas/CollaborationFollowV1", + "description": "Subscription settings; null when not following.", + "nullable": true + }, + "following": { + "description": "Whether the caller follows the record.", + "nullable": true, + "type": "boolean" + } + }, + "type": "object" + }, + "CollaborationFollowV1": { + "description": "A subscription to record changes and comments.", + "properties": { + "id": { + "description": "Subscription identifier.", + "nullable": true, + "type": "integer" + }, + "mutedUntil": { + "description": "Notifications muted until this time, if set.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "notifyOnChange": { + "description": "Receive record change digests.", + "nullable": true, + "type": "boolean" + }, + "notifyOnComment": { + "description": "Receive new comment notifications.", + "nullable": true, + "type": "boolean" + }, + "reason": { + "description": "How following began.", + "enum": [ + "MANUAL", + "AUTHOR", + "COMMENTED", + "MENTIONED", + "ASSIGNED", + "SHARED" + ], + "nullable": true, + "type": "string" + }, + "userDisplayName": { + "description": "Follower display name.", + "nullable": true, + "type": "string" + }, + "userId": { + "description": "Follower identity.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationFollowerListV1": { + "description": "Subscriptions for this record.", + "properties": { + "items": { + "description": "Subscriptions for this record.", + "items": { + "$ref": "#/components/schemas/CollaborationFollowV1" + }, + "nullable": true, + "type": "array" + }, + "nextCursor": { + "description": "Opaque continuation token; null when finished or the service has no continuation support.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationLinkV1": { + "properties": { + "label": { + "description": "label.", + "nullable": true, + "type": "string" + }, + "url": { + "description": "url.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationMentionCandidateListV1": { + "description": "Candidates ranked with record participants first.", + "properties": { + "items": { + "description": "Candidates ranked with record participants first.", + "items": { + "$ref": "#/components/schemas/CollaborationMentionCandidateV1" + }, + "nullable": true, + "type": "array" + }, + "nextCursor": { + "description": "Opaque continuation token; null when finished or the service has no continuation support.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationMentionCandidateV1": { + "description": "A matching person and their known parent access.", + "properties": { + "canRead": { + "description": "Recipient access: string true, false, or unknown when it cannot be established.", + "enum": [ + "true", + "false", + "unknown" + ], + "nullable": true, + "type": "string" + }, + "person": { + "$ref": "#/components/schemas/CollaborationPersonV1", + "description": "Directory identity.", + "nullable": true + } + }, + "type": "object" + }, + "CollaborationMentionV1": { + "description": "A mention embedded in a comment.", + "properties": { + "userId": { + "description": "Mentioned user identity.", + "nullable": true, + "type": "string" + }, + "visible": { + "description": "Whether recipient access was confirmed when mentioned.", + "nullable": true, + "type": "boolean" + } + }, + "type": "object" + }, + "CollaborationMutationResultV1": { + "description": "Acknowledgement of a completed mutation.", + "properties": { + "success": { + "description": "True after the requested operation completes.", + "nullable": true, + "type": "boolean" + } + }, + "type": "object" + }, + "CollaborationMyWorkV1": { + "properties": { + "assignedRecordsByTable": { + "additionalProperties": { + "type": "integer" + }, + "description": "assignedRecordsByTable.", + "nullable": true, + "type": "object" + }, + "openTaskCount": { + "description": "openTaskCount.", + "nullable": true, + "type": "integer" + }, + "tasks": { + "description": "tasks.", + "items": { + "$ref": "#/components/schemas/CollaborationTaskV1" + }, + "nullable": true, + "type": "array" + }, + "unreadMentionCount": { + "description": "unreadMentionCount.", + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "CollaborationPersonListV1": { + "description": "Matching active directory entries.", + "properties": { + "items": { + "description": "Matching active directory entries.", + "items": { + "$ref": "#/components/schemas/CollaborationPersonV1" + }, + "nullable": true, + "type": "array" + }, + "nextCursor": { + "description": "Opaque continuation token; null when finished or the service has no continuation support.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationPersonV1": { + "description": "An active directory entry.", + "properties": { + "displayName": { + "description": "Display name.", + "nullable": true, + "type": "string" + }, + "email": { + "description": "Directory email, if known.", + "nullable": true, + "type": "string" + }, + "lastSeenAt": { + "description": "Most recent directory refresh time.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "userId": { + "description": "Stable user identity.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationPresenceLeaveV1": { + "description": "Remove the caller's lease on this connection and target.", + "properties": { + "connectionId": { + "description": "Client connection identity.", + "nullable": false, + "type": "string" + }, + "pk": { + "description": "Optional parent key.", + "nullable": true, + "type": "string" + }, + "table": { + "description": "Parent table name.", + "nullable": false, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationPresenceRequestV1": { + "description": "Renew a 45-second presence lease; send every 20 seconds.", + "properties": { + "connectionId": { + "description": "Client connection identity.", + "nullable": false, + "type": "string" + }, + "fieldName": { + "description": "Optional focused field on a record.", + "nullable": true, + "type": "string" + }, + "mode": { + "description": "VIEWING or EDITING.", + "enum": [ + "VIEWING", + "EDITING" + ], + "nullable": false, + "type": "string" + }, + "pk": { + "description": "Optional parent key; omit for a table view.", + "nullable": true, + "type": "string" + }, + "table": { + "description": "Parent table name.", + "nullable": false, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationPresenceSnapshotV1": { + "description": "Live viewers, merged across tabs; presence.changed uses this payload.", + "properties": { + "pk": { + "description": "Record key; absent for table events.", + "nullable": true, + "type": "string" + }, + "table": { + "description": "Parent table name.", + "nullable": false, + "type": "string" + }, + "viewers": { + "items": { + "$ref": "#/components/schemas/CollaborationPresenceViewerV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "CollaborationPresenceViewerV1": { + "description": "One user merged across live tabs; EDITING takes precedence.", + "properties": { + "displayName": { + "description": "Session display name.", + "nullable": false, + "type": "string" + }, + "fieldName": { + "description": "Focused field; null on table snapshots.", + "nullable": true, + "type": "string" + }, + "mode": { + "description": "VIEWING or EDITING.", + "enum": [ + "VIEWING", + "EDITING" + ], + "nullable": false, + "type": "string" + }, + "userId": { + "description": "Stable user identity.", + "nullable": false, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationRecentListV1": { + "description": "Most recent visible targets, at most fifty.", + "properties": { + "items": { + "description": "Most recent visible targets, at most fifty.", + "items": { + "$ref": "#/components/schemas/CollaborationFavoriteV1" + }, + "nullable": true, + "type": "array" + }, + "nextCursor": { + "description": "Opaque continuation token; null when finished or the service has no continuation support.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationShareListV1": { + "properties": { + "items": { + "description": "items.", + "items": { + "$ref": "#/components/schemas/CollaborationShareV1" + }, + "nullable": true, + "type": "array" + } + }, + "type": "object" + }, + "CollaborationSharePreviewV1": { + "properties": { + "recipients": { + "description": "recipients.", + "items": { + "$ref": "#/components/schemas/CollaborationShareRecipientV1" + }, + "nullable": true, + "type": "array" + } + }, + "type": "object" + }, + "CollaborationShareRecipientV1": { + "properties": { + "canRead": { + "description": "canRead.", + "nullable": true, + "type": "boolean" + }, + "displayName": { + "description": "displayName.", + "nullable": true, + "type": "string" + }, + "userId": { + "description": "userId.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationShareRequestV1": { + "properties": { + "message": { + "description": "message.", + "nullable": true, + "type": "string" + }, + "toUserIds": { + "description": "toUserIds.", + "items": { + "type": "string" + }, + "nullable": true, + "type": "array" + } + }, + "type": "object" + }, + "CollaborationShareV1": { + "properties": { + "fromDisplayName": { + "description": "Sender display name.", + "nullable": true, + "type": "string" + }, + "fromUserId": { + "description": "fromUserId.", + "nullable": true, + "type": "string" + }, + "id": { + "description": "id.", + "nullable": true, + "type": "integer" + }, + "message": { + "description": "message.", + "nullable": true, + "type": "string" + }, + "recipientCouldRead": { + "description": "recipientCouldRead.", + "nullable": true, + "type": "boolean" + }, + "recordId": { + "description": "recordId.", + "nullable": true, + "type": "string" + }, + "sentAt": { + "description": "sentAt.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "tableName": { + "description": "tableName.", + "nullable": true, + "type": "string" + }, + "toDisplayName": { + "description": "Recipient display name.", + "nullable": true, + "type": "string" + }, + "toUserId": { + "description": "toUserId.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationTagApplyRequestV1": { + "description": "Add and remove tag associations in one request.", + "properties": { + "add": { + "description": "Tag identifiers to add; omitted means none.", + "items": { + "type": "integer" + }, + "nullable": true, + "type": "array" + }, + "remove": { + "description": "Tag identifiers to remove; omitted means none.", + "items": { + "type": "integer" + }, + "nullable": true, + "type": "array" + } + }, + "type": "object" + }, + "CollaborationTagCreateRequestV1": { + "description": "Create a tag or suggest one under the table policy.", + "properties": { + "color": { + "description": "Optional display color.", + "nullable": true, + "type": "string" + }, + "label": { + "description": "Required display label, 1 to 60 characters.", + "nullable": true, + "type": "string" + }, + "table": { + "description": "Required table metadata name.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationTagListV1": { + "description": "Available or applied tags.", + "properties": { + "items": { + "description": "Available or applied tags.", + "items": { + "$ref": "#/components/schemas/CollaborationTagV1" + }, + "nullable": true, + "type": "array" + }, + "nextCursor": { + "description": "Opaque continuation token; null when finished or the service has no continuation support.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationTagV1": { + "description": "An approved tag or the caller's pending suggestion.", + "properties": { + "approved": { + "description": "Whether anyone may apply this tag.", + "nullable": true, + "type": "boolean" + }, + "color": { + "description": "Optional display color.", + "nullable": true, + "type": "string" + }, + "id": { + "description": "Tag identifier.", + "nullable": true, + "type": "integer" + }, + "label": { + "description": "Display label.", + "nullable": true, + "type": "string" + }, + "name": { + "description": "Normalized vocabulary name.", + "nullable": true, + "type": "string" + }, + "tableName": { + "description": "Table scope; null means global.", + "nullable": true, + "type": "string" + }, + "usageCount": { + "description": "Number of record associations.", + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "CollaborationTargetRequestV1": { + "description": "Target to star, unstar, or record as recently viewed.", + "properties": { + "recordId": { + "description": "Required for RECORD; omitted otherwise.", + "nullable": true, + "type": "string" + }, + "targetName": { + "description": "Required metadata name.", + "nullable": true, + "type": "string" + }, + "targetType": { + "description": "Required target kind.", + "enum": [ + "TABLE", + "APP", + "RECORD", + "PROCESS", + "REPORT", + "SAVED_VIEW" + ], + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationTaskCreateRequestV1": { + "properties": { + "assigneeUserId": { + "description": "assigneeUserId.", + "nullable": true, + "type": "string" + }, + "dueAt": { + "description": "dueAt.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "notes": { + "description": "notes.", + "nullable": true, + "type": "string" + }, + "remindAt": { + "description": "remindAt.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "title": { + "description": "title.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationTaskListV1": { + "properties": { + "items": { + "description": "items.", + "items": { + "$ref": "#/components/schemas/CollaborationTaskV1" + }, + "nullable": true, + "type": "array" + }, + "nextCursor": { + "description": "nextCursor.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationTaskPatchRequestV1": { + "properties": { + "assigneeUserId": { + "description": "assigneeUserId.", + "nullable": true, + "type": "string" + }, + "dueAt": { + "description": "dueAt.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "notes": { + "description": "notes.", + "nullable": true, + "type": "string" + }, + "remindAt": { + "description": "remindAt.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "status": { + "description": "status.", + "nullable": true, + "type": "string" + }, + "title": { + "description": "title.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationTaskV1": { + "properties": { + "assigneeDisplayName": { + "description": "Assignee display name.", + "nullable": true, + "type": "string" + }, + "assigneeUserId": { + "description": "assigneeUserId.", + "nullable": true, + "type": "string" + }, + "completedAt": { + "description": "completedAt.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "completedByDisplayName": { + "description": "Display name of the person who completed the task.", + "nullable": true, + "type": "string" + }, + "completedByUserId": { + "description": "completedByUserId.", + "nullable": true, + "type": "string" + }, + "createdByDisplayName": { + "description": "Creator display name.", + "nullable": true, + "type": "string" + }, + "createdByUserId": { + "description": "createdByUserId.", + "nullable": true, + "type": "string" + }, + "dueAt": { + "description": "dueAt.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "id": { + "description": "id.", + "nullable": true, + "type": "integer" + }, + "notes": { + "description": "notes.", + "nullable": true, + "type": "string" + }, + "recordId": { + "description": "recordId.", + "nullable": true, + "type": "string" + }, + "remindAt": { + "description": "remindAt.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "status": { + "description": "status.", + "nullable": true, + "type": "string" + }, + "tableName": { + "description": "tableName.", + "nullable": true, + "type": "string" + }, + "title": { + "description": "title.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationTimelineDetailV1": { + "description": "A permitted field change from a core audit.", + "properties": { + "fieldName": { + "description": "Changed field metadata name.", + "nullable": true, + "type": "string" + }, + "message": { + "description": "Optional audit message.", + "nullable": true, + "type": "string" + }, + "newValue": { + "description": "New display value.", + "nullable": true, + "type": "string" + }, + "oldValue": { + "description": "Previous display value.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationTimelineItemV1": { + "description": "One visible event in the merged record timeline.", + "properties": { + "actorName": { + "description": "Actor display name.", + "nullable": true, + "type": "string" + }, + "actorUserId": { + "description": "Actor identity, when known.", + "nullable": true, + "type": "string" + }, + "at": { + "description": "Event time.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "details": { + "description": "Field details filtered by caller permissions.", + "items": { + "$ref": "#/components/schemas/CollaborationTimelineDetailV1" + }, + "nullable": true, + "type": "array" + }, + "id": { + "description": "Identifier within the source.", + "nullable": true, + "type": "integer" + }, + "kind": { + "description": "Event source.", + "enum": [ + "ACTIVITY", + "AUDIT" + ], + "nullable": true, + "type": "string" + }, + "refId": { + "description": "Related record key.", + "nullable": true, + "type": "string" + }, + "refTable": { + "description": "Related table metadata name.", + "nullable": true, + "type": "string" + }, + "summary": { + "description": "Human-readable event summary.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "CollaborationTimelinePageV1": { + "description": "Merged events, newest first.", + "properties": { + "items": { + "description": "Merged events, newest first.", + "items": { + "$ref": "#/components/schemas/CollaborationTimelineItemV1" + }, + "nullable": true, + "type": "array" + }, + "nextCursor": { + "description": "Opaque continuation token; null when finished or the service has no continuation support.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "DataAnalysisAxisV1": { + "nullable": true, + "properties": { + "field": { + "description": "Field.", + "nullable": true, + "type": "string" + }, + "label": { + "description": "Label.", + "nullable": true, + "type": "string" + }, + "valueType": { + "description": "Value type.", + "enum": [ + "COUNT", + "DECIMAL", + "PERCENT", + "DATE", + "DATE_TIME", + "DURATION", + "TEXT" + ], + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "DataAnalysisCandidateKeyV1": { + "nullable": true, + "properties": { + "fields": { + "description": "Readable fields to include; omit for all analyzable fields on a table profile.", + "items": { + "type": "string" + }, + "nullable": true, + "type": "array" + }, + "rowCount": { + "description": "Row count.", + "nullable": true, + "type": "integer" + }, + "drill": { + "$ref": "#/components/schemas/DataAnalysisDrillV1", + "description": "Open the matching records using this table and QueryFilter; null when suppressed.", + "nullable": true + } + }, + "type": "object" + }, + "DataAnalysisCapabilitiesV1": { + "nullable": true, + "properties": { + "canAnalyze": { + "description": "Whether this session may analyze the table; false responses expose no fields.", + "nullable": true, + "type": "boolean" + }, + "tableName": { + "description": "Table name.", + "nullable": true, + "type": "string" + }, + "tableLabel": { + "description": "Table label.", + "nullable": true, + "type": "string" + }, + "fields": { + "description": "Readable fields to include; omit for all analyzable fields on a table profile.", + "items": { + "$ref": "#/components/schemas/DataAnalysisCapabilityFieldV1" + }, + "nullable": true, + "type": "array" + }, + "limits": { + "$ref": "#/components/schemas/DataAnalysisLimitsV1", + "description": "Limits.", + "nullable": true + }, + "backendCapabilities": { + "description": "Backend capabilities.", + "items": { + "type": "string" + }, + "nullable": true, + "type": "array" + }, + "sqlWorkbenchAvailable": { + "description": "Whether SQL Workbench metadata is installed in this instance.", + "nullable": true, + "type": "boolean" + } + }, + "type": "object" + }, + "DataAnalysisCapabilityFieldV1": { + "nullable": true, + "properties": { + "name": { + "description": "Name.", + "nullable": true, + "type": "string" + }, + "label": { + "description": "Label.", + "nullable": true, + "type": "string" + }, + "type": { + "description": "Type.", + "nullable": true, + "type": "string" + }, + "kind": { + "description": "Semantic field kind: NUMERIC, DATE, DATE_TIME, TEXT, BOOLEAN or CATEGORY.", + "nullable": true, + "type": "string" + }, + "defaultChartKind": { + "description": "Default chart kind.", + "enum": [ + "HISTOGRAM", + "BOX", + "BAR", + "PARETO", + "TIME_SERIES", + "SCATTER", + "HEATMAP" + ], + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "DataAnalysisChartV1": { + "nullable": true, + "properties": { + "stacked": { + "description": "Stack category series to a total share of one when true.", + "nullable": true, + "type": "boolean" + }, + "kind": { + "description": "Semantic field kind: NUMERIC, DATE, DATE_TIME, TEXT, BOOLEAN or CATEGORY.", + "enum": [ + "HISTOGRAM", + "BOX", + "BAR", + "PARETO", + "TIME_SERIES", + "SCATTER", + "HEATMAP" + ], + "nullable": true, + "type": "string" + }, + "alternatives": { + "description": "Alternatives.", + "items": { + "enum": [ + "HISTOGRAM", + "BOX", + "BAR", + "PARETO", + "TIME_SERIES", + "SCATTER", + "HEATMAP" + ], + "type": "string" + }, + "nullable": true, + "type": "array" + }, + "x": { + "$ref": "#/components/schemas/DataAnalysisAxisV1", + "description": "X.", + "nullable": true + }, + "y": { + "$ref": "#/components/schemas/DataAnalysisAxisV1", + "description": "Y.", + "nullable": true + }, + "series": { + "description": "Series.", + "items": { + "$ref": "#/components/schemas/DataAnalysisSeriesV1" + }, + "nullable": true, + "type": "array" + }, + "annotations": { + "description": "Annotations.", + "items": { + "type": "string" + }, + "nullable": true, + "type": "array" + } + }, + "type": "object" + }, + "DataAnalysisColumnProfileRequestV1": { + "additionalProperties": false, + "properties": { + "filter": { + "$ref": "#/components/schemas/QueryFilter", + "description": "Core QueryFilter JSON, identical to the table query and count endpoints." + }, + "exact": { + "description": "Request exact computation instead of the configured estimate.", + "type": "boolean" + }, + "fieldName": { + "description": "Readable field name to profile or enumerate.", + "type": "string" + } + }, + "required": [ + "fieldName" + ], + "type": "object" + }, + "DataAnalysisColumnProfileV1": { + "nullable": true, + "properties": { + "tableName": { + "description": "Table name.", + "nullable": true, + "type": "string" + }, + "filter": { + "$ref": "#/components/schemas/QueryFilter", + "description": "Core QueryFilter JSON, identical to the table query and count endpoints.", + "nullable": true + }, + "estimate": { + "description": "True when statistics describe a sample rather than the entire filtered population.", + "nullable": true, + "type": "boolean" + }, + "sampleRows": { + "description": "Actual number of rows in the sample, not an extrapolated count.", + "nullable": true, + "type": "integer" + }, + "truncated": { + "description": "True when the row limit prevented a complete scan.", + "nullable": true, + "type": "boolean" + }, + "rowsScanned": { + "description": "Number of source rows included in computation.", + "nullable": true, + "type": "integer" + }, + "asOf": { + "description": "As of.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "dataVersion": { + "description": "Data version.", + "nullable": true, + "type": "string" + }, + "warnings": { + "description": "Warnings.", + "items": { + "type": "string" + }, + "nullable": true, + "type": "array" + }, + "fieldName": { + "description": "Readable field name to profile or enumerate.", + "nullable": true, + "type": "string" + }, + "fieldLabel": { + "description": "Field label.", + "nullable": true, + "type": "string" + }, + "fieldType": { + "description": "Field type.", + "nullable": true, + "type": "string" + }, + "counts": { + "description": "Counts.", + "items": { + "$ref": "#/components/schemas/DataAnalysisMetricV1" + }, + "nullable": true, + "type": "array" + }, + "numeric": { + "$ref": "#/components/schemas/DataAnalysisNumericProfileV1", + "description": "Numeric.", + "nullable": true + }, + "dates": { + "$ref": "#/components/schemas/DataAnalysisDateProfileV1", + "description": "Dates.", + "nullable": true + }, + "text": { + "$ref": "#/components/schemas/DataAnalysisTextProfileV1", + "description": "Text.", + "nullable": true + }, + "booleans": { + "description": "Booleans.", + "items": { + "$ref": "#/components/schemas/DataAnalysisMetricV1" + }, + "nullable": true, + "type": "array" + }, + "topValues": { + "description": "Top values.", + "items": { + "$ref": "#/components/schemas/DataAnalysisValueCountV1" + }, + "nullable": true, + "type": "array" + }, + "chart": { + "$ref": "#/components/schemas/DataAnalysisChartV1", + "description": "Chart.", + "nullable": true + } + }, + "type": "object" + }, + "DataAnalysisCompareRequestV1": { + "properties": { + "filterA": { + "$ref": "#/components/schemas/QueryFilter", + "description": "Population A filter; null selects the whole permitted table.", + "nullable": true + }, + "filterB": { + "$ref": "#/components/schemas/QueryFilter", + "description": "Population B filter; null selects the whole permitted table.", + "nullable": true + }, + "labelA": { + "description": "Display name of population A; default A.", + "type": "string" + }, + "labelB": { + "description": "Display name of population B; default B.", + "type": "string" + }, + "fields": { + "description": "Distinct FULL fields to analyze; correlation requires 2 to 12 numeric fields.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "fields" + ], + "type": "object" + }, + "DataAnalysisCompareV1": { + "properties": { + "fields": { + "description": "Distinct FULL fields to analyze; correlation requires 2 to 12 numeric fields.", + "items": { + "$ref": "#/components/schemas/DataAnalysisFieldComparisonV1" + }, + "nullable": true, + "type": "array" + } + }, + "type": "object" + }, + "DataAnalysisComparisonSideV1": { + "properties": { + "label": { + "description": "Label.", + "nullable": true, + "type": "string" + }, + "metrics": { + "description": "Typed metrics with exact population drills unless privacy suppresses them.", + "items": { + "$ref": "#/components/schemas/DataAnalysisMetricV1" + }, + "nullable": true, + "type": "array" + } + }, + "type": "object" + }, + "DataAnalysisComparisonValueV1": { + "properties": { + "value": { + "description": "Value.", + "nullable": true + }, + "label": { + "description": "Label.", + "nullable": true, + "type": "string" + }, + "sideA": { + "$ref": "#/components/schemas/DataAnalysisComparisonSideV1", + "description": "Side a.", + "nullable": true + }, + "sideB": { + "$ref": "#/components/schemas/DataAnalysisComparisonSideV1", + "description": "Side b.", + "nullable": true + }, + "delta": { + "$ref": "#/components/schemas/DataAnalysisMetricV1", + "description": "B minus A, in original units (share differences are fractions).", + "nullable": true + }, + "percentDelta": { + "$ref": "#/components/schemas/DataAnalysisMetricV1", + "description": "(B minus A) divided by absolute A, a fraction; null at a zero baseline.", + "nullable": true + }, + "significance": { + "$ref": "#/components/schemas/DataAnalysisSignificanceV1", + "description": "Test assumptions, two-sided p-value, degrees of freedom and plain-language conclusion.", + "nullable": true + } + }, + "type": "object" + }, + "DataAnalysisCorrelationCellV1": { + "properties": { + "xField": { + "description": "FULL numeric field on the x axis.", + "nullable": true, + "type": "string" + }, + "yField": { + "description": "FULL numeric field on the y axis.", + "nullable": true, + "type": "string" + }, + "n": { + "description": "Pairwise non-null population count; null when privacy suppresses it.", + "nullable": true, + "type": "integer" + }, + "r": { + "description": "Pearson correlation; null for insufficient data, zero variance or privacy suppression.", + "nullable": true, + "type": "number" + }, + "scatter": { + "$ref": "#/components/schemas/DataAnalysisScatterRequestV1", + "description": "POST the included parameters to the table scatter endpoint.", + "nullable": true + } + }, + "type": "object" + }, + "DataAnalysisCorrelationRequestV1": { + "properties": { + "filter": { + "$ref": "#/components/schemas/QueryFilter", + "description": "Current-user query filter; record locks and core field rules apply.", + "nullable": true + }, + "fields": { + "description": "Distinct FULL fields to analyze; correlation requires 2 to 12 numeric fields.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "fields" + ], + "type": "object" + }, + "DataAnalysisCorrelationV1": { + "properties": { + "fields": { + "description": "Distinct FULL fields to analyze; correlation requires 2 to 12 numeric fields.", + "items": { + "type": "string" + }, + "nullable": true, + "type": "array" + }, + "cells": { + "description": "Cells.", + "items": { + "$ref": "#/components/schemas/DataAnalysisCorrelationCellV1" + }, + "nullable": true, + "type": "array" + }, + "chart": { + "$ref": "#/components/schemas/DataAnalysisChartV1", + "description": "Semantic series; category comparisons are grouped and category time series are stacked.", + "nullable": true + } + }, + "type": "object" + }, + "DataAnalysisCrosstabCellV1": { + "properties": { + "rowIndex": { + "description": "Row index.", + "nullable": true, + "type": "integer" + }, + "columnIndex": { + "description": "Column index.", + "nullable": true, + "type": "integer" + }, + "count": { + "$ref": "#/components/schemas/DataAnalysisMetricV1", + "description": "Cell count with its exact drill, or a suppressed metric.", + "nullable": true + }, + "rowShare": { + "$ref": "#/components/schemas/DataAnalysisMetricV1", + "description": "Cell count divided by row total; suppressed if it could disclose a hidden cell.", + "nullable": true + }, + "columnShare": { + "$ref": "#/components/schemas/DataAnalysisMetricV1", + "description": "Cell count divided by column total; suppressed if it could disclose a hidden cell.", + "nullable": true + } + }, + "type": "object" + }, + "DataAnalysisCrosstabRequestV1": { + "properties": { + "filter": { + "$ref": "#/components/schemas/QueryFilter", + "description": "Current-user query filter; record locks and core field rules apply.", + "nullable": true + }, + "rowField": { + "description": "FULL field defining crosstab rows.", + "type": "string" + }, + "columnField": { + "description": "FULL field defining crosstab columns.", + "type": "string" + }, + "limit": { + "description": "Maximum sample points (1 to 2000, default 2000) or kept crosstab categories per axis (1 to 20, default 20).", + "type": "integer" + } + }, + "required": [ + "rowField", + "columnField" + ], + "type": "object" + }, + "DataAnalysisCrosstabV1": { + "properties": { + "rows": { + "description": "Rows.", + "items": { + "$ref": "#/components/schemas/DataAnalysisPivotHeaderV1" + }, + "nullable": true, + "type": "array" + }, + "columns": { + "description": "Columns.", + "items": { + "$ref": "#/components/schemas/DataAnalysisPivotHeaderV1" + }, + "nullable": true, + "type": "array" + }, + "cells": { + "description": "Cells.", + "items": { + "$ref": "#/components/schemas/DataAnalysisCrosstabCellV1" + }, + "nullable": true, + "type": "array" + }, + "significance": { + "$ref": "#/components/schemas/DataAnalysisSignificanceV1", + "description": "Test assumptions, two-sided p-value, degrees of freedom and plain-language conclusion.", + "nullable": true + } + }, + "type": "object" + }, + "DataAnalysisDateProfileV1": { + "nullable": true, + "properties": { + "metrics": { + "description": "Metrics.", + "items": { + "$ref": "#/components/schemas/DataAnalysisMetricV1" + }, + "nullable": true, + "type": "array" + }, + "unit": { + "description": "Unit.", + "nullable": true, + "type": "string" + }, + "buckets": { + "description": "Buckets.", + "items": { + "$ref": "#/components/schemas/DataAnalysisValueCountV1" + }, + "nullable": true, + "type": "array" + }, + "gaps": { + "description": "Gaps.", + "items": { + "$ref": "#/components/schemas/DataAnalysisValueCountV1" + }, + "nullable": true, + "type": "array" + }, + "dayOfWeek": { + "description": "Day of week.", + "items": { + "$ref": "#/components/schemas/DataAnalysisValueCountV1" + }, + "nullable": true, + "type": "array" + }, + "hourOfDay": { + "description": "Hour of day.", + "items": { + "$ref": "#/components/schemas/DataAnalysisValueCountV1" + }, + "nullable": true, + "type": "array" + } + }, + "type": "object" + }, + "DataAnalysisDistinctValuesPageV1": { + "nullable": true, + "properties": { + "tableName": { + "description": "Table name.", + "nullable": true, + "type": "string" + }, + "filter": { + "$ref": "#/components/schemas/QueryFilter", + "description": "Core QueryFilter JSON, identical to the table query and count endpoints.", + "nullable": true + }, + "estimate": { + "description": "True when statistics describe a sample rather than the entire filtered population.", + "nullable": true, + "type": "boolean" + }, + "sampleRows": { + "description": "Actual number of rows in the sample, not an extrapolated count.", + "nullable": true, + "type": "integer" + }, + "truncated": { + "description": "True when the row limit prevented a complete scan.", + "nullable": true, + "type": "boolean" + }, + "rowsScanned": { + "description": "Number of source rows included in computation.", + "nullable": true, + "type": "integer" + }, + "asOf": { + "description": "As of.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "dataVersion": { + "description": "Data version.", + "nullable": true, + "type": "string" + }, + "warnings": { + "description": "Warnings.", + "items": { + "type": "string" + }, + "nullable": true, + "type": "array" + }, + "fieldName": { + "description": "Readable field name to profile or enumerate.", + "nullable": true, + "type": "string" + }, + "page": { + "description": "Zero-based page number.", + "nullable": true, + "type": "integer" + }, + "pageSize": { + "description": "Maximum values per page, from 1 to 500.", + "nullable": true, + "type": "integer" + }, + "hasMore": { + "description": "Has more.", + "nullable": true, + "type": "boolean" + }, + "totalDistinct": { + "description": "Total distinct.", + "nullable": true, + "type": "integer" + }, + "values": { + "description": "Values.", + "items": { + "$ref": "#/components/schemas/DataAnalysisValueCountV1" + }, + "nullable": true, + "type": "array" + } + }, + "type": "object" + }, + "DataAnalysisDistinctValuesRequestV1": { + "additionalProperties": false, + "properties": { + "filter": { + "$ref": "#/components/schemas/QueryFilter", + "description": "Core QueryFilter JSON, identical to the table query and count endpoints." + }, + "fieldName": { + "description": "Readable field name to profile or enumerate.", + "type": "string" + }, + "page": { + "description": "Zero-based page number.", + "type": "integer" + }, + "pageSize": { + "description": "Maximum values per page, from 1 to 500.", + "type": "integer" + }, + "search": { + "description": "Optional search text applied to stored values.", + "type": "string" + } + }, + "required": [ + "fieldName" + ], + "type": "object" + }, + "DataAnalysisDrillV1": { + "nullable": true, + "properties": { + "tableName": { + "description": "Table name.", + "nullable": true, + "type": "string" + }, + "filter": { + "$ref": "#/components/schemas/QueryFilter", + "description": "Core QueryFilter JSON, identical to the table query and count endpoints.", + "nullable": true + } + }, + "type": "object" + }, + "DataAnalysisDuplicatesRequestV1": { + "additionalProperties": false, + "properties": { + "filter": { + "$ref": "#/components/schemas/QueryFilter", + "description": "Core QueryFilter JSON, identical to the table query and count endpoints." + }, + "fields": { + "description": "Readable fields to include; omit for all analyzable fields on a table profile.", + "items": { + "type": "string" + }, + "type": "array" + }, + "limit": { + "description": "Maximum duplicate groups to return, from 1 to 500; default 50.", + "type": "integer" + } + }, + "required": [ + "fields" + ], + "type": "object" + }, + "DataAnalysisDuplicatesResultV1": { + "nullable": true, + "properties": { + "tableName": { + "description": "Table name.", + "nullable": true, + "type": "string" + }, + "filter": { + "$ref": "#/components/schemas/QueryFilter", + "description": "Core QueryFilter JSON, identical to the table query and count endpoints.", + "nullable": true + }, + "estimate": { + "description": "True when statistics describe a sample rather than the entire filtered population.", + "nullable": true, + "type": "boolean" + }, + "sampleRows": { + "description": "Actual number of rows in the sample, not an extrapolated count.", + "nullable": true, + "type": "integer" + }, + "truncated": { + "description": "True when the row limit prevented a complete scan.", + "nullable": true, + "type": "boolean" + }, + "rowsScanned": { + "description": "Number of source rows included in computation.", + "nullable": true, + "type": "integer" + }, + "asOf": { + "description": "As of.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "dataVersion": { + "description": "Data version.", + "nullable": true, + "type": "string" + }, + "warnings": { + "description": "Warnings.", + "items": { + "type": "string" + }, + "nullable": true, + "type": "array" + }, + "fields": { + "description": "Readable fields to include; omit for all analyzable fields on a table profile.", + "items": { + "type": "string" + }, + "nullable": true, + "type": "array" + }, + "groups": { + "description": "Groups.", + "items": { + "$ref": "#/components/schemas/DataAnalysisValueCountV1" + }, + "nullable": true, + "type": "array" + } + }, + "type": "object" + }, + "DataAnalysisFieldComparisonV1": { + "properties": { + "field": { + "description": "FULL field whose distribution is compared over time.", + "nullable": true, + "type": "string" + }, + "values": { + "description": "Values.", + "items": { + "$ref": "#/components/schemas/DataAnalysisComparisonValueV1" + }, + "nullable": true, + "type": "array" + }, + "significance": { + "$ref": "#/components/schemas/DataAnalysisSignificanceV1", + "description": "Test assumptions, two-sided p-value, degrees of freedom and plain-language conclusion.", + "nullable": true + }, + "chart": { + "$ref": "#/components/schemas/DataAnalysisChartV1", + "description": "Semantic series; category comparisons are grouped and category time series are stacked.", + "nullable": true + } + }, + "type": "object" + }, + "DataAnalysisFieldSummaryV1": { + "nullable": true, + "properties": { + "field": { + "description": "Field.", + "nullable": true, + "type": "string" + }, + "label": { + "description": "Label.", + "nullable": true, + "type": "string" + }, + "type": { + "description": "Type.", + "nullable": true, + "type": "string" + }, + "completeness": { + "description": "Non-empty share as a 0..1 ratio rounded to six decimals.", + "nullable": true, + "type": "number" + }, + "distinct": { + "description": "Distinct.", + "nullable": true, + "type": "integer" + }, + "uniqueness": { + "description": "Distinct share as a 0..1 ratio rounded to six decimals.", + "nullable": true, + "type": "number" + }, + "constant": { + "description": "Constant.", + "nullable": true, + "type": "boolean" + }, + "empty": { + "description": "Empty.", + "nullable": true, + "type": "boolean" + }, + "nulls": { + "$ref": "#/components/schemas/DataAnalysisMetricV1", + "description": "Nulls.", + "nullable": true + }, + "blanks": { + "$ref": "#/components/schemas/DataAnalysisMetricV1", + "description": "Blanks.", + "nullable": true + } + }, + "type": "object" + }, + "DataAnalysisFileV1": { + "format": "binary", + "type": "string" + }, + "DataAnalysisLimitsV1": { + "nullable": true, + "properties": { + "maxRows": { + "description": "Max rows.", + "nullable": true, + "type": "integer" + }, + "sampleThresholdRows": { + "description": "Sample threshold rows.", + "nullable": true, + "type": "integer" + }, + "sampleRows": { + "description": "Actual number of rows in the sample, not an extrapolated count.", + "nullable": true, + "type": "integer" + }, + "minGroupSize": { + "description": "Min group size.", + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "DataAnalysisMetricV1": { + "nullable": true, + "properties": { + "key": { + "description": "Key.", + "nullable": true, + "type": "string" + }, + "label": { + "description": "Plain-English metric label, ready to display.", + "nullable": true, + "type": "string" + }, + "value": { + "description": "Raw numeric or temporal value. PERCENT is a 0..1 ratio rounded to six decimals; DECIMAL field statistics have ten significant digits. DATE_TIME is an ISO instant.", + "nullable": true, + "oneOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "nullable": true, + "type": "object" + } + ] + }, + "valueType": { + "description": "Value type.", + "enum": [ + "COUNT", + "DECIMAL", + "PERCENT", + "DATE", + "DATE_TIME", + "DURATION", + "TEXT" + ], + "nullable": true, + "type": "string" + }, + "estimate": { + "description": "Whether this metric is estimated; the population rows metric remains exact.", + "type": "boolean" + }, + "formatted": { + "description": "Display-ready value, including grouping, field display formats, percent signs and session-zone dates; null when absent or suppressed.", + "nullable": true, + "type": "string" + }, + "drill": { + "$ref": "#/components/schemas/DataAnalysisDrillV1", + "description": "Open the matching records using this table and QueryFilter; null when suppressed.", + "nullable": true + }, + "suppressed": { + "description": "Suppressed.", + "nullable": true, + "type": "boolean" + }, + "suppressedReason": { + "description": "Suppressed reason.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "DataAnalysisNumericProfileV1": { + "nullable": true, + "properties": { + "metrics": { + "description": "Metrics.", + "items": { + "$ref": "#/components/schemas/DataAnalysisMetricV1" + }, + "nullable": true, + "type": "array" + }, + "histogram": { + "description": "Histogram.", + "items": { + "$ref": "#/components/schemas/DataAnalysisValueCountV1" + }, + "nullable": true, + "type": "array" + }, + "outliers": { + "description": "Outliers.", + "items": { + "$ref": "#/components/schemas/DataAnalysisValueCountV1" + }, + "nullable": true, + "type": "array" + } + }, + "type": "object" + }, + "DataAnalysisPivotCellV1": { + "properties": { + "rowIndex": { + "description": "Zero-based index in rowHeaders.", + "type": "integer" + }, + "columnIndex": { + "description": "Zero-based index in columnHeaders.", + "type": "integer" + }, + "values": { + "description": "Metrics in requested measure order; suppressed metrics have no value or drill.", + "items": { + "$ref": "#/components/schemas/DataAnalysisMetricV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "DataAnalysisPivotDimensionV1": { + "properties": { + "field": { + "description": "FULL field name, optionally joinTable.field through an exposed join.", + "type": "string" + }, + "dateBucket": { + "description": "Optional calendar or cyclic bucket in the session timezone.", + "enum": [ + "YEAR", + "QUARTER", + "MONTH", + "WEEK", + "DAY", + "HOUR", + "DAY_OF_WEEK", + "HOUR_OF_DAY" + ], + "type": "string" + }, + "numericBins": { + "$ref": "#/components/schemas/DataAnalysisPivotNumericBinsV1", + "description": "Optional equal-width numeric bins; mutually exclusive with dateBucket." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + "DataAnalysisPivotHeaderV1": { + "properties": { + "value": { + "description": "Typed group key; null for a blank group or Other.", + "nullable": true + }, + "label": { + "description": "Display label, including Other (k groups).", + "type": "string" + } + }, + "type": "object" + }, + "DataAnalysisPivotMeasureInfoV1": { + "properties": { + "key": { + "description": "Stable measure key by request position.", + "type": "string" + }, + "label": { + "description": "Display label.", + "type": "string" + }, + "valueType": { + "description": "Semantic metric type.", + "enum": [ + "COUNT", + "DECIMAL", + "PERCENT", + "DATE", + "DATE_TIME", + "DURATION", + "TEXT" + ], + "type": "string" + } + }, + "type": "object" + }, + "DataAnalysisPivotMeasureV1": { + "properties": { + "operator": { + "description": "Aggregate operator. COUNT counts records, including null values.", + "enum": [ + "COUNT", + "SUM", + "AVG", + "MIN", + "MAX", + "COUNT_DISTINCT", + "PERCENTILE" + ], + "type": "string" + }, + "field": { + "description": "FULL field to aggregate; optional for COUNT.", + "type": "string" + }, + "percentile": { + "description": "PERCENTILE only: percentile_cont fraction from 0 to 1.", + "type": "number" + } + }, + "required": [ + "operator" + ], + "type": "object" + }, + "DataAnalysisPivotNumericBinsV1": { + "properties": { + "count": { + "description": "Number of bins, 1–200; defaults to 20.", + "type": "integer" + }, + "min": { + "description": "Optional explicit lower bound; otherwise a nice enclosing edge.", + "type": "number" + }, + "max": { + "description": "Optional explicit upper bound; final interior bin includes this value.", + "type": "number" + } + }, + "type": "object" + }, + "DataAnalysisPivotRequestV1": { + "properties": { + "filter": { + "$ref": "#/components/schemas/QueryFilter", + "description": "User query filter, passed through for core enforcement." + }, + "rows": { + "description": "One to three row dimensions.", + "items": { + "$ref": "#/components/schemas/DataAnalysisPivotDimensionV1" + }, + "type": "array" + }, + "columns": { + "description": "Zero to two column dimensions; defaults to empty.", + "items": { + "$ref": "#/components/schemas/DataAnalysisPivotDimensionV1" + }, + "type": "array" + }, + "values": { + "description": "One to six measures.", + "items": { + "$ref": "#/components/schemas/DataAnalysisPivotMeasureV1" + }, + "type": "array" + }, + "showTotals": { + "description": "Include row, column and grand totals; defaults to true.", + "type": "boolean" + }, + "limitGroups": { + "description": "Kept groups per dimension; default 50, maximum 200.", + "type": "integer" + } + }, + "required": [ + "rows", + "values" + ], + "type": "object" + }, + "DataAnalysisPivotV1": { + "properties": { + "rowHeaders": { + "description": "Row header tuples in cell-index order.", + "items": { + "items": { + "$ref": "#/components/schemas/DataAnalysisPivotHeaderV1" + }, + "type": "array" + }, + "type": "array" + }, + "columnHeaders": { + "description": "Column header tuples; an empty tuple represents no column dimensions.", + "items": { + "items": { + "$ref": "#/components/schemas/DataAnalysisPivotHeaderV1" + }, + "type": "array" + }, + "type": "array" + }, + "measures": { + "description": "Measure metadata in request order.", + "items": { + "$ref": "#/components/schemas/DataAnalysisPivotMeasureInfoV1" + }, + "type": "array" + }, + "cells": { + "description": "Sparse cells; absent combinations are not materialized.", + "items": { + "$ref": "#/components/schemas/DataAnalysisPivotCellV1" + }, + "type": "array" + }, + "rowTotals": { + "description": "Metric tuples aligned with rowHeaders; empty when totals disabled.", + "items": { + "items": { + "$ref": "#/components/schemas/DataAnalysisMetricV1" + }, + "type": "array" + }, + "type": "array" + }, + "columnTotals": { + "description": "Metric tuples aligned with columnHeaders; empty when totals disabled.", + "items": { + "items": { + "$ref": "#/components/schemas/DataAnalysisMetricV1" + }, + "type": "array" + }, + "type": "array" + }, + "grandTotals": { + "description": "Grand-total metrics; empty when totals disabled.", + "items": { + "$ref": "#/components/schemas/DataAnalysisMetricV1" + }, + "type": "array" + }, + "truncatedRows": { + "description": "Row groups were merged into Other.", + "type": "boolean" + }, + "truncatedColumns": { + "description": "Column groups were merged into Other.", + "type": "boolean" + }, + "estimate": { + "description": "True when bounded streamed fallback produced a partial result.", + "type": "boolean" + }, + "warnings": { + "description": "Privacy, partial-result and joined-drill limitations.", + "items": { + "type": "string" + }, + "type": "array" + }, + "asOf": { + "description": "UTC timestamp of computation.", + "type": "string" + } + }, + "type": "object" + }, + "DataAnalysisPointV1": { + "nullable": true, + "properties": { + "x": { + "description": "X.", + "nullable": true, + "oneOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "nullable": true, + "type": "object" + } + ] + }, + "y": { + "description": "Y.", + "nullable": true, + "type": "number" + }, + "label": { + "description": "Label.", + "nullable": true, + "type": "string" + }, + "drill": { + "$ref": "#/components/schemas/DataAnalysisDrillV1", + "description": "Open the matching records using this table and QueryFilter; null when suppressed.", + "nullable": true + } + }, + "type": "object" + }, + "DataAnalysisRunStartedV1": { + "nullable": true, + "properties": { + "runId": { + "description": "Run id.", + "nullable": true, + "type": "string" + }, + "status": { + "description": "Status.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "DataAnalysisRunStatusV1": { + "nullable": true, + "properties": { + "runId": { + "description": "Run id.", + "nullable": true, + "type": "string" + }, + "status": { + "description": "Status.", + "nullable": true, + "type": "string" + }, + "error": { + "description": "Error.", + "nullable": true, + "type": "string" + }, + "columnProfile": { + "$ref": "#/components/schemas/DataAnalysisColumnProfileV1", + "description": "Completed column result; null for other operations or unfinished runs.", + "nullable": true + }, + "tableProfile": { + "$ref": "#/components/schemas/DataAnalysisTableProfileV1", + "description": "Completed table result; null for other operations or unfinished runs.", + "nullable": true + }, + "startedAt": { + "description": "Started at.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "finishedAt": { + "description": "Finished at.", + "format": "date-time", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "DataAnalysisSavedEntryV1": { + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "tableName": { + "type": "string" + }, + "tableLabel": { + "type": "string" + }, + "owner": { + "type": "string" + }, + "updated": { + "format": "date-time", + "nullable": true, + "type": "string" + }, + "shared": { + "type": "boolean" + }, + "starred": { + "type": "boolean" + } + }, + "type": "object" + }, + "DataAnalysisSavedListV1": { + "properties": { + "analyses": { + "items": { + "$ref": "#/components/schemas/DataAnalysisSavedEntryV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "DataAnalysisSavedRequestV1": { + "properties": { + "kind": { + "enum": [ + "COLUMN_PROFILE", + "TABLE_PROFILE", + "PIVOT", + "COMPARE", + "CORRELATION", + "CROSSTAB", + "SHIFT" + ], + "type": "string" + }, + "tableName": { + "description": "Source QQQ table name; required for ad hoc export, supplied by the path for SQL.", + "type": "string" + }, + "request": { + "anyOf": [ + { + "$ref": "#/components/schemas/DataAnalysisColumnProfileRequestV1" + }, + { + "$ref": "#/components/schemas/DataAnalysisTableProfileRequestV1" + }, + { + "$ref": "#/components/schemas/DataAnalysisPivotRequestV1" + }, + { + "$ref": "#/components/schemas/DataAnalysisCompareRequestV1" + }, + { + "$ref": "#/components/schemas/DataAnalysisCorrelationRequestV1" + }, + { + "$ref": "#/components/schemas/DataAnalysisCrosstabRequestV1" + }, + { + "$ref": "#/components/schemas/DataAnalysisShiftRequestV1" + } + ], + "description": "Typed request matching kind. Field names, filters and dimensions use the existing analysis request contracts." + }, + "format": { + "description": "Required for export; ignored for SQL.", + "enum": [ + "csv", + "xlsx" + ], + "type": "string" + } + }, + "required": [ + "kind", + "request" + ], + "type": "object" + }, + "DataAnalysisSavedResultV1": { + "properties": { + "kind": { + "enum": [ + "COLUMN_PROFILE", + "TABLE_PROFILE", + "PIVOT", + "COMPARE", + "CORRELATION", + "CROSSTAB", + "SHIFT" + ], + "type": "string" + }, + "warnings": { + "items": { + "type": "string" + }, + "type": "array" + }, + "columnProfile": { + "$ref": "#/components/schemas/DataAnalysisColumnProfileV1", + "nullable": true + }, + "compare": { + "$ref": "#/components/schemas/DataAnalysisCompareV1", + "nullable": true + }, + "correlation": { + "$ref": "#/components/schemas/DataAnalysisCorrelationV1", + "nullable": true + }, + "crosstab": { + "$ref": "#/components/schemas/DataAnalysisCrosstabV1", + "nullable": true + }, + "pivot": { + "$ref": "#/components/schemas/DataAnalysisPivotV1", + "nullable": true + }, + "shift": { + "$ref": "#/components/schemas/DataAnalysisShiftV1", + "nullable": true + }, + "tableProfile": { + "$ref": "#/components/schemas/DataAnalysisTableProfileV1", + "nullable": true + } + }, + "type": "object" + }, + "DataAnalysisScatterRequestV1": { + "properties": { + "tableName": { + "description": "Table for the scatter link; route parameter takes precedence.", + "nullable": true, + "type": "string" + }, + "exact": { + "description": "Compatibility flag; scatter always returns the bounded sample.", + "nullable": true, + "type": "boolean" + }, + "filter": { + "$ref": "#/components/schemas/QueryFilter", + "description": "Current-user query filter; record locks and core field rules apply.", + "nullable": true + }, + "xField": { + "description": "FULL numeric field on the x axis.", + "type": "string" + }, + "yField": { + "description": "FULL numeric field on the y axis.", + "type": "string" + }, + "limit": { + "description": "Maximum sample points (1 to 2000, default 2000) or kept crosstab categories per axis (1 to 20, default 20).", + "type": "integer" + } + }, + "required": [ + "xField", + "yField" + ], + "type": "object" + }, + "DataAnalysisScatterV1": { + "properties": { + "n": { + "description": "Pairwise non-null population count; null when privacy suppresses it.", + "nullable": true, + "type": "integer" + }, + "sampleSize": { + "description": "Number of displayed paired records.", + "nullable": true, + "type": "integer" + }, + "sampling": { + "description": "Sampling method; core query currently uses a deterministic primary-key prefix.", + "nullable": true, + "type": "string" + }, + "points": { + "description": "Points.", + "items": { + "$ref": "#/components/schemas/DataAnalysisPointV1" + }, + "nullable": true, + "type": "array" + }, + "trend": { + "$ref": "#/components/schemas/DataAnalysisTrendLineV1", + "description": "Least-squares slope, intercept and r fitted to the displayed sample.", + "nullable": true + }, + "chart": { + "$ref": "#/components/schemas/DataAnalysisChartV1", + "description": "Semantic series; category comparisons are grouped and category time series are stacked.", + "nullable": true + } + }, + "type": "object" + }, + "DataAnalysisSeriesV1": { + "nullable": true, + "properties": { + "name": { + "description": "Name.", + "nullable": true, + "type": "string" + }, + "points": { + "description": "Points.", + "items": { + "$ref": "#/components/schemas/DataAnalysisPointV1" + }, + "nullable": true, + "type": "array" + } + }, + "type": "object" + }, + "DataAnalysisShiftBucketV1": { + "properties": { + "value": { + "description": "Value.", + "nullable": true + }, + "label": { + "description": "Label.", + "nullable": true, + "type": "string" + }, + "complete": { + "description": "True when the calendar bucket end has passed in the session timezone.", + "nullable": true, + "type": "boolean" + }, + "metrics": { + "description": "Typed metrics with exact population drills unless privacy suppresses them.", + "items": { + "$ref": "#/components/schemas/DataAnalysisMetricV1" + }, + "nullable": true, + "type": "array" + } + }, + "type": "object" + }, + "DataAnalysisShiftRequestV1": { + "properties": { + "filter": { + "$ref": "#/components/schemas/QueryFilter", + "description": "Current-user query filter; record locks and core field rules apply.", + "nullable": true + }, + "field": { + "description": "FULL field whose distribution is compared over time.", + "type": "string" + }, + "dateField": { + "description": "FULL DATE or DATE_TIME field for session-timezone calendar buckets.", + "type": "string" + }, + "bucket": { + "description": "Calendar unit: HOUR, DAY, WEEK, MONTH, QUARTER or YEAR; default MONTH.", + "type": "string" + } + }, + "required": [ + "field", + "dateField" + ], + "type": "object" + }, + "DataAnalysisShiftV1": { + "properties": { + "buckets": { + "description": "Buckets.", + "items": { + "$ref": "#/components/schemas/DataAnalysisShiftBucketV1" + }, + "nullable": true, + "type": "array" + }, + "psi": { + "$ref": "#/components/schemas/DataAnalysisMetricV1", + "description": "Population stability index, null when inapplicable; zero shares are floored at 0.000001.", + "nullable": true + }, + "sentence": { + "description": "Plain-language result or reason the statistic is not applicable.", + "nullable": true, + "type": "string" + }, + "chart": { + "$ref": "#/components/schemas/DataAnalysisChartV1", + "description": "Semantic series; category comparisons are grouped and category time series are stacked.", + "nullable": true + } + }, + "type": "object" + }, + "DataAnalysisSignificanceV1": { + "properties": { + "test": { + "description": "Test.", + "nullable": true, + "type": "string" + }, + "statistic": { + "description": "Statistic.", + "nullable": true, + "type": "number" + }, + "df": { + "description": "Degrees of freedom; null when undefined.", + "nullable": true, + "type": "number" + }, + "pValue": { + "description": "Two-sided p-value; p >= 0.05 is never significant.", + "nullable": true, + "type": "number" + }, + "applicable": { + "description": "Whether all test validity and privacy requirements hold.", + "nullable": true, + "type": "boolean" + }, + "sentence": { + "description": "Plain-language result or reason the statistic is not applicable.", + "nullable": true, + "type": "string" + }, + "cramersV": { + "description": "Cramer association strength computed on the pooled contingency table; null when invalid.", + "nullable": true, + "type": "number" + } + }, + "type": "object" + }, + "DataAnalysisSqlV1": { + "properties": { + "available": { + "type": "boolean" + }, + "note": { + "type": "string" + }, + "sql": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "DataAnalysisStarV1": { + "properties": { + "starred": { + "type": "boolean" + } + }, + "type": "object" + }, + "DataAnalysisStartRunRequestV1": { + "additionalProperties": false, + "properties": { + "operation": { + "description": "COLUMN_PROFILE or TABLE_PROFILE.", + "enum": [ + "COLUMN_PROFILE", + "TABLE_PROFILE" + ], + "type": "string" + }, + "tableName": { + "description": "Table name.", + "type": "string" + }, + "request": { + "description": "Profile parameters for the selected operation, without tableName.", + "oneOf": [ + { + "$ref": "#/components/schemas/DataAnalysisColumnProfileRequestV1" + }, + { + "$ref": "#/components/schemas/DataAnalysisTableProfileRequestV1" + } + ] + } + }, + "required": [ + "operation", + "tableName", + "request" + ], + "type": "object" + }, + "DataAnalysisTableProfileRequestV1": { + "additionalProperties": false, + "properties": { + "filter": { + "$ref": "#/components/schemas/QueryFilter", + "description": "Core QueryFilter JSON, identical to the table query and count endpoints." + }, + "fields": { + "description": "Readable fields to include; omit for all analyzable fields on a table profile.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "DataAnalysisTableProfileV1": { + "nullable": true, + "properties": { + "tableName": { + "description": "Table name.", + "nullable": true, + "type": "string" + }, + "filter": { + "$ref": "#/components/schemas/QueryFilter", + "description": "Core QueryFilter JSON, identical to the table query and count endpoints.", + "nullable": true + }, + "estimate": { + "description": "True when statistics describe a sample rather than the entire filtered population.", + "nullable": true, + "type": "boolean" + }, + "sampleRows": { + "description": "Actual number of rows in the sample, not an extrapolated count.", + "nullable": true, + "type": "integer" + }, + "truncated": { + "description": "True when the row limit prevented a complete scan.", + "nullable": true, + "type": "boolean" + }, + "rowsScanned": { + "description": "Number of source rows included in computation.", + "nullable": true, + "type": "integer" + }, + "asOf": { + "description": "As of.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "dataVersion": { + "description": "Data version.", + "nullable": true, + "type": "string" + }, + "warnings": { + "description": "Warnings.", + "items": { + "type": "string" + }, + "nullable": true, + "type": "array" + }, + "rowCount": { + "$ref": "#/components/schemas/DataAnalysisMetricV1", + "description": "Row count.", + "nullable": true + }, + "fields": { + "description": "Readable fields to include; omit for all analyzable fields on a table profile.", + "items": { + "$ref": "#/components/schemas/DataAnalysisFieldSummaryV1" + }, + "nullable": true, + "type": "array" + }, + "heatmap": { + "$ref": "#/components/schemas/DataAnalysisChartV1", + "description": "Heatmap.", + "nullable": true + }, + "candidateKeys": { + "description": "Candidate keys.", + "items": { + "$ref": "#/components/schemas/DataAnalysisCandidateKeyV1" + }, + "nullable": true, + "type": "array" + } + }, + "type": "object" + }, + "DataAnalysisTextProfileV1": { + "nullable": true, + "properties": { + "metrics": { + "description": "Metrics.", + "items": { + "$ref": "#/components/schemas/DataAnalysisMetricV1" + }, + "nullable": true, + "type": "array" + }, + "histogram": { + "description": "Histogram.", + "items": { + "$ref": "#/components/schemas/DataAnalysisValueCountV1" + }, + "nullable": true, + "type": "array" + }, + "patterns": { + "description": "Patterns.", + "items": { + "$ref": "#/components/schemas/DataAnalysisValueCountV1" + }, + "nullable": true, + "type": "array" + }, + "sampleRows": { + "description": "Actual number of rows in the sample, not an extrapolated count.", + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "DataAnalysisTrendLineV1": { + "properties": { + "slope": { + "description": "Slope.", + "nullable": true, + "type": "number" + }, + "intercept": { + "description": "Intercept.", + "nullable": true, + "type": "number" + }, + "r": { + "description": "Pearson correlation; null for insufficient data, zero variance or privacy suppression.", + "nullable": true, + "type": "number" + } + }, + "type": "object" + }, + "DataAnalysisValueCountV1": { + "nullable": true, + "properties": { + "value": { + "description": "Value.", + "nullable": true, + "oneOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "nullable": true, + "type": "object" + } + ] + }, + "label": { + "description": "Label.", + "nullable": true, + "type": "string" + }, + "count": { + "description": "Count.", + "nullable": true, + "type": "integer" + }, + "share": { + "description": "Share as a 0..1 ratio rounded to six decimals.", + "nullable": true, + "type": "number" + }, + "drill": { + "$ref": "#/components/schemas/DataAnalysisDrillV1", + "description": "Open the matching records using this table and QueryFilter; null when suppressed.", + "nullable": true + } + }, + "type": "object" + }, + "DataAnalysisWatchBucketV1": { + "properties": { + "start": { + "description": "Calendar date or hour-start instant in the user's time zone.", + "type": "string" + }, + "value": { + "nullable": true, + "type": "number" + }, + "categories": { + "items": { + "type": "string" + }, + "type": "array" + }, + "drill": { + "$ref": "#/components/schemas/DataAnalysisDrillV1", + "nullable": true + } + }, + "type": "object" + }, + "DataAnalysisWatchPreviewV1": { + "properties": { + "series": { + "items": { + "$ref": "#/components/schemas/DataAnalysisWatchBucketV1" + }, + "type": "array" + }, + "chart": { + "$ref": "#/components/schemas/DataAnalysisChartV1", + "description": "TIME_SERIES with baseline band annotations." + }, + "verdict": { + "$ref": "#/components/schemas/DataAnalysisWatchVerdictV1" + } + }, + "type": "object" + }, + "DataAnalysisWatchVerdictV1": { + "properties": { + "evaluated": { + "description": "False for insufficient history or privacy suppression; must not resolve an alert.", + "type": "boolean" + }, + "firing": { + "type": "boolean" + }, + "value": { + "nullable": true, + "type": "number" + }, + "baseline": { + "nullable": true, + "type": "number" + }, + "baselineLow": { + "nullable": true, + "type": "number" + }, + "baselineHigh": { + "nullable": true, + "type": "number" + }, + "message": { + "type": "string" + }, + "drill": { + "$ref": "#/components/schemas/DataAnalysisDrillV1", + "nullable": true + } + }, + "type": "object" + }, + "DbPerformanceActivityV1": { + "properties": { + "blockingChains": { + "items": { + "$ref": "#/components/schemas/DbPerformanceBlockingChainV1" + }, + "type": "array" + }, + "liveTextRedacted": { + "type": "boolean" + }, + "sessions": { + "items": { + "$ref": "#/components/schemas/DbPerformanceSessionV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "DbPerformanceBlockingChainV1": { + "properties": { + "blockedPids": { + "items": { + "nullable": true, + "type": "integer" + }, + "type": "array" + }, + "rootPid": { + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "DbPerformanceErrorV1": { + "properties": { + "error": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "DbPerformanceExplainRequestV1": { + "description": "Supply exactly one of statementId or sql. Parameters are strings, accepted only for ANALYZE and never stored.", + "properties": { + "backend": { + "nullable": true, + "type": "string" + }, + "mode": { + "enum": [ + "PLAN", + "ANALYZE" + ], + "type": "string" + }, + "parameters": { + "items": { + "nullable": true, + "type": "string" + }, + "type": "array" + }, + "sql": { + "nullable": true, + "type": "string" + }, + "statementId": { + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "DbPerformanceExplainResultV1": { + "properties": { + "actualTotalMs": { + "nullable": true, + "type": "number" + }, + "assistantPrompt": { + "nullable": true, + "type": "string" + }, + "explainId": { + "nullable": true, + "type": "integer" + }, + "mode": { + "nullable": true, + "type": "string" + }, + "planJson": { + "nullable": true, + "type": "string" + }, + "planText": { + "nullable": true, + "type": "string" + }, + "sqlWorkbenchUrl": { + "nullable": true, + "type": "string" + }, + "totalCost": { + "nullable": true, + "type": "number" + }, + "warnings": { + "items": { + "nullable": true, + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "DbPerformanceFindingV1": { + "properties": { + "id": { + "nullable": true, + "type": "integer" + }, + "score": { + "nullable": true, + "type": "number" + }, + "severity": { + "nullable": true, + "type": "string" + }, + "title": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "DbPerformanceLookupV1": { + "properties": { + "fingerprint": { + "nullable": true, + "type": "string" + }, + "matches": { + "items": { + "$ref": "#/components/schemas/DbPerformanceStatementV1" + }, + "type": "array" + }, + "normalizedSql": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "DbPerformanceOverviewV1": { + "properties": { + "findingsBySeverity": { + "additionalProperties": { + "nullable": true, + "type": "integer" + }, + "type": "object" + }, + "settings": { + "$ref": "#/components/schemas/DbPerformanceSettingsV1" + }, + "snapshot": { + "$ref": "#/components/schemas/DbPerformanceSnapshotV1" + }, + "topFindings": { + "items": { + "$ref": "#/components/schemas/DbPerformanceFindingV1" + }, + "type": "array" + }, + "topStatements": { + "items": { + "$ref": "#/components/schemas/DbPerformanceStatementV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "DbPerformanceSessionV1": { + "properties": { + "application": { + "nullable": true, + "type": "string" + }, + "blockedBy": { + "items": { + "nullable": true, + "type": "integer" + }, + "type": "array" + }, + "blockingCount": { + "nullable": true, + "type": "integer" + }, + "fingerprint": { + "nullable": true, + "type": "string" + }, + "liveTextRedacted": { + "type": "boolean" + }, + "normalizedText": { + "nullable": true, + "type": "string" + }, + "pid": { + "nullable": true, + "type": "integer" + }, + "query": { + "description": "Raw live SQL only with view_live_text; never persisted.", + "nullable": true, + "type": "string" + }, + "querySeconds": { + "nullable": true, + "type": "number" + }, + "state": { + "nullable": true, + "type": "string" + }, + "user": { + "nullable": true, + "type": "string" + }, + "waitEvent": { + "nullable": true, + "type": "string" + }, + "xactSeconds": { + "nullable": true, + "type": "number" + } + }, + "type": "object" + }, + "DbPerformanceSettingsV1": { + "properties": { + "lastSnapshotAt": { + "nullable": true, + "type": "string" + }, + "provider": { + "nullable": true, + "type": "string" + }, + "statsAccess": { + "nullable": true, + "type": "string" + }, + "statsAccessMessage": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "DbPerformanceSnapshotV1": { + "properties": { + "cacheHitRatio": { + "nullable": true, + "type": "number" + }, + "capturedAt": { + "nullable": true, + "type": "string" + }, + "connectionsTotal": { + "nullable": true, + "type": "integer" + }, + "deadlocks": { + "nullable": true, + "type": "integer" + }, + "id": { + "nullable": true, + "type": "integer" + }, + "maxConnections": { + "nullable": true, + "type": "integer" + }, + "statementCalls": { + "nullable": true, + "type": "integer" + }, + "statementTotalMs": { + "nullable": true, + "type": "number" + }, + "status": { + "nullable": true, + "type": "string" + }, + "tempBytes": { + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "DbPerformanceStatementV1": { + "properties": { + "calls24h": { + "nullable": true, + "type": "integer" + }, + "historyPath": { + "nullable": true, + "type": "string" + }, + "hitRatio": { + "nullable": true, + "type": "number" + }, + "id": { + "nullable": true, + "type": "integer" + }, + "meanMs24h": { + "nullable": true, + "type": "number" + }, + "queryText": { + "description": "Normalized SQL, truncated to 300 characters.", + "nullable": true, + "type": "string" + }, + "shareOfDbTime24h": { + "nullable": true, + "type": "number" + }, + "totalMs24h": { + "nullable": true, + "type": "number" + } + }, + "type": "object" + }, + "EdiAckV1": { + "description": "Concatenated acknowledgement previews; type is 997, 999, TA1, CONTRL, NONE or MIXED. text is null for PHI.", + "properties": { + "text": { + "nullable": true, + "type": "string" + }, + "type": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "EdiAssociationV1": { + "description": "Direct QQQ association and its target fields.", + "properties": { + "fields": { + "items": { + "$ref": "#/components/schemas/EdiFieldV1" + }, + "type": "array" + }, + "label": { + "nullable": true, + "type": "string" + }, + "name": { + "nullable": true, + "type": "string" + }, + "table": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "EdiDiffV1": { + "description": "Only differing records are returned. Both lists are empty for PHI.", + "properties": { + "againstExpected": { + "items": { + "$ref": "#/components/schemas/EdiDifferenceV1" + }, + "type": "array" + }, + "againstPreviousRevision": { + "items": { + "$ref": "#/components/schemas/EdiDifferenceV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "EdiDifferenceV1": { + "description": "One document comparison; documentIndex is zero based.", + "properties": { + "after": { + "additionalProperties": true, + "nullable": true, + "type": "object" + }, + "before": { + "description": "Expected JSON or a previous mapped record.", + "nullable": true + }, + "documentIndex": { + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "EdiElementV1": { + "description": "Element or composite component; codes contain at most 200 active codes in lexical order.", + "properties": { + "codeListId": { + "nullable": true, + "type": "integer" + }, + "codes": { + "items": { + "nullable": true, + "type": "string" + }, + "type": "array" + }, + "component": { + "nullable": true, + "type": "integer" + }, + "id": { + "nullable": true, + "type": "string" + }, + "maxLength": { + "nullable": true, + "type": "integer" + }, + "minLength": { + "nullable": true, + "type": "integer" + }, + "name": { + "nullable": true, + "type": "string" + }, + "position": { + "nullable": true, + "type": "integer" + }, + "type": { + "nullable": true, + "type": "string" + }, + "usage": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "EdiErrorV1": { + "description": "Deprecated since 1.1.0: errors use BasicErrorResponseV1.", + "properties": { + "error": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "EdiFieldV1": { + "description": "QQQ target field metadata.", + "properties": { + "label": { + "nullable": true, + "type": "string" + }, + "name": { + "nullable": true, + "type": "string" + }, + "possibleValueSourceName": { + "nullable": true, + "type": "string" + }, + "required": { + "type": "boolean" + }, + "type": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "EdiFindingV1": { + "description": "Value-free diagnostic. PHI messages are generic; only positions and codes are retained.", + "properties": { + "code": { + "nullable": true, + "type": "string" + }, + "elementPosition": { + "nullable": true, + "type": "integer" + }, + "loopId": { + "nullable": true, + "type": "string" + }, + "message": { + "nullable": true, + "type": "string" + }, + "segmentId": { + "nullable": true, + "type": "string" + }, + "segmentPosition": { + "nullable": true, + "type": "integer" + }, + "severity": { + "nullable": true, + "type": "string" + }, + "snipLevel": { + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "EdiGuideTreeV1": { + "description": "Ordered guide tree. Root segments are outside loops; nested loops retain parent scope.", + "properties": { + "loops": { + "items": { + "$ref": "#/components/schemas/EdiLoopV1" + }, + "type": "array" + }, + "segments": { + "items": { + "$ref": "#/components/schemas/EdiSegmentV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "EdiLoopV1": { + "description": "Guide loop, nested within its parent; repeat is the maximum occurrence count.", + "properties": { + "id": { + "nullable": true, + "type": "string" + }, + "loops": { + "items": { + "$ref": "#/components/schemas/EdiLoopV1" + }, + "type": "array" + }, + "repeat": { + "nullable": true, + "type": "integer" + }, + "segments": { + "items": { + "$ref": "#/components/schemas/EdiSegmentV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "EdiParseV1": { + "description": "Counts of wire interchanges, groups and documents.", + "properties": { + "documents": { + "nullable": true, + "type": "integer" + }, + "groups": { + "nullable": true, + "type": "integer" + }, + "interchanges": { + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "EdiPreviewRequestV1": { + "description": "mapId is required. Supply exactly one of sampleId or sampleBase64. Uploads are at most 5 MiB decoded, stored encrypted. ruleOverrides replaces the whole rule set in memory. CURRENT (default) uses the newest active guide in the pinned guide family; ORIGINAL uses the pinned guide.", + "properties": { + "guideRevision": { + "enum": [ + "CURRENT", + "ORIGINAL" + ], + "nullable": true, + "type": "string" + }, + "mapId": { + "nullable": true, + "type": "integer" + }, + "ruleOverrides": { + "items": { + "$ref": "#/components/schemas/EdiRuleV1" + }, + "nullable": true, + "type": "array" + }, + "sampleBase64": { + "format": "byte", + "maxLength": 6990508, + "nullable": true, + "type": "string" + }, + "sampleId": { + "nullable": true, + "type": "integer" + }, + "sampleName": { + "maxLength": 255, + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "EdiPreviewV1": { + "description": "Parse, validate, acknowledge and map without target writes. PHI suppresses result, ack text, and both diffs.", + "properties": { + "ack": { + "$ref": "#/components/schemas/EdiAckV1" + }, + "diff": { + "$ref": "#/components/schemas/EdiDiffV1" + }, + "findings": { + "items": { + "$ref": "#/components/schemas/EdiFindingV1" + }, + "type": "array" + }, + "parse": { + "$ref": "#/components/schemas/EdiParseV1" + }, + "phiSuppressed": { + "type": "boolean" + }, + "result": { + "$ref": "#/components/schemas/EdiResultV1", + "nullable": true + } + }, + "type": "object" + }, + "EdiRecordV1": { + "description": "Field values and recursively associated records. Values use the target table field types.", + "properties": { + "associations": { + "additionalProperties": { + "items": { + "$ref": "#/components/schemas/EdiRecordV1" + }, + "type": "array" + }, + "type": "object" + }, + "values": { + "additionalProperties": true, + "type": "object" + } + }, + "type": "object" + }, + "EdiResultV1": { + "description": "Mapped records in document order; no target writes.", + "properties": { + "records": { + "items": { + "$ref": "#/components/schemas/EdiRecordV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "EdiRuleErrorsV1": { + "description": "Correlate errors using zero-based index, optional id and sequence.", + "properties": { + "errors": { + "items": { + "nullable": true, + "type": "string" + }, + "type": "array" + }, + "id": { + "nullable": true, + "type": "integer" + }, + "index": { + "nullable": true, + "type": "integer" + }, + "sequence": { + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "EdiRuleV1": { + "description": "Map rule. id is optional for unsaved rules. transformArgs is a JSON object encoded as a string, as in core table CRUD.", + "properties": { + "condition": { + "nullable": true, + "type": "string" + }, + "defaultValue": { + "nullable": true, + "type": "string" + }, + "ediPath": { + "nullable": true, + "type": "string" + }, + "id": { + "nullable": true, + "type": "integer" + }, + "qqqPath": { + "nullable": true, + "type": "string" + }, + "required": { + "nullable": true, + "type": "boolean" + }, + "sequence": { + "nullable": true, + "type": "integer" + }, + "transform": { + "nullable": true, + "type": "string" + }, + "transformArgs": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "EdiSegmentV1": { + "description": "Segment definition in guide sequence order.", + "properties": { + "elements": { + "items": { + "$ref": "#/components/schemas/EdiElementV1" + }, + "type": "array" + }, + "id": { + "nullable": true, + "type": "string" + }, + "max": { + "nullable": true, + "type": "integer" + }, + "min": { + "nullable": true, + "type": "integer" + }, + "name": { + "nullable": true, + "type": "string" + }, + "position": { + "nullable": true, + "type": "string" + }, + "usage": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "EdiTargetV1": { + "description": "Target metadata visible to the caller, current rules and registered transforms.", + "properties": { + "associations": { + "items": { + "$ref": "#/components/schemas/EdiAssociationV1" + }, + "type": "array" + }, + "fields": { + "items": { + "$ref": "#/components/schemas/EdiFieldV1" + }, + "type": "array" + }, + "rules": { + "items": { + "$ref": "#/components/schemas/EdiRuleV1" + }, + "type": "array" + }, + "table": { + "nullable": true, + "type": "string" + }, + "transforms": { + "items": { + "$ref": "#/components/schemas/EdiTransformV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "EdiTransformV1": { + "description": "Registered transform and JSON Schema describing its string-valued arguments.", + "properties": { + "argumentSchema": { + "additionalProperties": true, + "description": "JSON Schema: type, properties, required and additionalProperties. All transform arguments are strings.", + "type": "object" + }, + "name": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "EdiValidateRequestV1": { + "description": "rules is required and may be empty; rules are never persisted.", + "properties": { + "rules": { + "items": { + "$ref": "#/components/schemas/EdiRuleV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "EdiValidationV1": { + "description": "One result per submitted rule, including rules with no errors.", + "properties": { + "rules": { + "items": { + "$ref": "#/components/schemas/EdiRuleErrorsV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "QaCaptureCapabilityV1": { + "description": "What QA capture means for the signed-in user. Clients that see enabled=false do nothing else.", + "properties": { + "blurSelectors": { + "description": "CSS selectors to blur in recordings; empty when not enabled.", + "items": { + "type": "string" + }, + "type": "array" + }, + "canReport": { + "description": "Whether the user can file a report (Report a bug).", + "type": "boolean" + }, + "context": { + "$ref": "#/components/schemas/QaCaptureContextV1" + }, + "cspOrigins": { + "$ref": "#/components/schemas/QaCaptureCspOriginsV1" + }, + "enabled": { + "description": "Whether capture is on for this user.", + "type": "boolean" + }, + "provider": { + "description": "The provider name (for example jam); null when not enabled.", + "nullable": true, + "type": "string" + }, + "providerConfig": { + "allOf": [ + { + "$ref": "#/components/schemas/QaCaptureProviderConfigV1" + } + ], + "description": "Provider settings; null when not enabled.", + "nullable": true + }, + "qaMode": { + "$ref": "#/components/schemas/QaCaptureQaModeV1" + }, + "reason": { + "description": "Why capture is on or off.", + "enum": [ + "AUDIENCE", + "QA_MODE", + "OFF", + "NOT_CONFIGURED", + "NO_ACCESS", + "QA_MODE_OFF" + ], + "type": "string" + }, + "reportsHref": { + "description": "The QA reports screen, only when the user can view reports. Clients follow it, never build it.", + "nullable": true, + "type": "string" + }, + "requestIdHeader": { + "description": "The response header carrying the request id (X-Request-Id).", + "type": "string" + }, + "sanitizer": { + "allOf": [ + { + "$ref": "#/components/schemas/QaCaptureSanitizerV1" + } + ], + "description": "Redaction rules; null when not enabled.", + "nullable": true + } + }, + "type": "object" + }, + "QaCaptureContextV1": { + "description": "Server context for capture metadata.", + "properties": { + "backendVersion": { + "description": "The backend build version.", + "nullable": true, + "type": "string" + }, + "environment": { + "description": "The environment name.", + "type": "string" + }, + "node": { + "description": "The serving node.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "QaCaptureCspOriginsV1": { + "description": "Content-Security-Policy origins the provider needs; empty when not enabled.", + "properties": { + "connectSrc": { + "description": "connect-src sources.", + "items": { + "type": "string" + }, + "type": "array" + }, + "frameSrc": { + "description": "frame-src sources.", + "items": { + "type": "string" + }, + "type": "array" + }, + "scriptSrc": { + "description": "script-src sources.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "QaCaptureErrorV1": { + "description": "An error.", + "properties": { + "error": { + "description": "What went wrong.", + "type": "string" + } + }, + "type": "object" + }, + "QaCaptureProviderConfigV1": { + "description": "Provider settings for the browser. For Jam: teamId, recordingLinkId and the script URLs.", + "properties": { + "recordingLinkId": { + "description": "A reusable recording link id for in-app Report a bug; null when none is set.", + "nullable": true, + "type": "string" + }, + "scriptUrls": { + "description": "The provider's scripts, in load order.", + "items": { + "type": "string" + }, + "type": "array" + }, + "teamId": { + "description": "The provider team id.", + "type": "string" + } + }, + "type": "object" + }, + "QaCaptureQaModeV1": { + "description": "The user's self-serve QA mode switch.", + "properties": { + "active": { + "description": "Whether the user's QA mode is on.", + "type": "boolean" + }, + "available": { + "description": "Whether the user can switch QA mode (self-serve mode and the qa_capture.use_qa_mode permission).", + "type": "boolean" + }, + "preferenceSection": { + "description": "The user preference section holding the switch; null when unavailable.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "QaCaptureReportRequestV1": { + "description": "A new QA report. Only pageUrl is required.", + "properties": { + "appName": { + "description": "The current app.", + "nullable": true, + "type": "string" + }, + "frontendVersion": { + "description": "The client build version.", + "nullable": true, + "type": "string" + }, + "pageUrl": { + "description": "The page the user is on; sanitizer query parameters are removed.", + "type": "string" + }, + "processName": { + "description": "The current process.", + "nullable": true, + "type": "string" + }, + "recordId": { + "description": "The current record id.", + "nullable": true, + "type": "string" + }, + "requestIds": { + "description": "Recent X-Request-Id values (at most 50 are kept, each at most 128 characters).", + "items": { + "type": "string" + }, + "nullable": true, + "type": "array" + }, + "tableName": { + "description": "The current table.", + "nullable": true, + "type": "string" + }, + "title": { + "description": "A short title; defaults to the table and record, process, app or page.", + "nullable": true, + "type": "string" + }, + "userAgent": { + "description": "The browser user agent.", + "nullable": true, + "type": "string" + }, + "viewport": { + "description": "The viewport size, for example 1440x900.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "QaCaptureReportResultV1": { + "description": "The created report and how to open the provider's recorder for it.", + "properties": { + "id": { + "description": "The report id.", + "type": "integer" + }, + "recordingParams": { + "additionalProperties": { + "type": "string" + }, + "description": "Query parameters that open the recorder (Jam: jam-recording, jam-title, jam-reference); null when no recording link is configured.", + "nullable": true, + "type": "object" + }, + "reference": { + "description": "The report reference (qa-), matched by the provider webhook.", + "type": "string" + }, + "title": { + "description": "The report title.", + "type": "string" + } + }, + "type": "object" + }, + "QaCaptureSanitizerV1": { + "description": "Redaction rules applied in the browser before anything is sent to the provider.", + "properties": { + "bodyFieldNames": { + "description": "JSON keys (any depth, case-insensitive) and form fields replaced by the redaction text.", + "items": { + "type": "string" + }, + "type": "array" + }, + "dropPathPrefixes": { + "description": "Same-origin path prefixes whose request and response bodies are dropped.", + "items": { + "type": "string" + }, + "type": "array" + }, + "headerNames": { + "description": "Lowercase header names deleted from request and response headers.", + "items": { + "type": "string" + }, + "type": "array" + }, + "queryParamNames": { + "description": "Query parameters redacted in request URLs and the page URL.", + "items": { + "type": "string" + }, + "type": "array" + }, + "redaction": { + "description": "The replacement text.", + "type": "string" + }, + "valuePatterns": { + "description": "JavaScript RegExp sources applied with flag g to bodies and console arguments.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "QuickSearchErrorV1": { + "description": "Deprecated since 1.1.0: errors use BasicErrorResponseV1.", + "properties": { + "error": { + "description": "Framework error message.", + "nullable": false, + "type": "string" + } + }, + "type": "object" + }, + "QuickSearchIndexStatusV1": { + "properties": { + "countsCheckedAt": { + "description": "Saved validation completion; null when validation counts are unavailable.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "documentCount": { + "description": "Saved validation document count, else last indexing run count; not live.", + "format": "int64", + "nullable": true, + "type": "integer" + }, + "enabled": { + "description": "Whether this index is enabled.", + "nullable": false, + "type": "boolean" + }, + "lastError": { + "description": "Persisted indexing error; null when absent.", + "nullable": true, + "type": "string" + }, + "lastSuccessfulSync": { + "description": "Newest successful basepull/full-reindex/reconcile watermark.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "realTimeErrorCount": { + "description": "Persisted real-time indexing error count.", + "nullable": true, + "type": "integer" + }, + "sourceCount": { + "description": "Source count from saved IndexValidator report; null without validation.", + "format": "int64", + "nullable": true, + "type": "integer" + }, + "status": { + "description": "Persisted indexing state, such as ACTIVE or NEEDS_REINDEX.", + "nullable": true, + "type": "string" + }, + "tableName": { + "description": "Indexed source table metadata name.", + "nullable": false, + "type": "string" + } + }, + "type": "object" + }, + "QuickSearchStatusV1": { + "properties": { + "activeShards": { + "description": "Cluster health counter; null when unavailable.", + "nullable": true, + "type": "integer" + }, + "backlogTruncated": { + "description": "Counts are lower bounds when more than 1000 backlog rows exist.", + "nullable": false, + "type": "boolean" + }, + "checkedAt": { + "description": "Snapshot completion time; remains unchanged on cache hits.", + "format": "date-time", + "nullable": false, + "type": "string" + }, + "clusterHealth": { + "description": "OpenSearch health color; null when unknown.", + "nullable": true, + "type": "string" + }, + "clusterReachable": { + "description": "Whether OpenSearch answered; null when not probed.", + "nullable": true, + "type": "boolean" + }, + "exhausted": { + "description": "Exhausted failed events, from the same bounded backlog read.", + "nullable": true, + "type": "integer" + }, + "homeHref": { + "description": "Quick Search home link, including the configured metadata prefix.", + "nullable": false, + "type": "string" + }, + "indexes": { + "description": "At most 100 persisted index rows, ordered by id.", + "items": { + "$ref": "#/components/schemas/QuickSearchIndexStatusV1" + }, + "type": "array" + }, + "indexingPaused": { + "description": "Indexing is paused; search can still serve.", + "nullable": true, + "type": "boolean" + }, + "lastError": { + "description": "Last known indexing/search error or snapshot failure; null when absent.", + "nullable": true, + "type": "string" + }, + "lastSuccessfulSync": { + "description": "Newest successful indexing watermark; not a guarantee all tables are current.", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "nodes": { + "description": "Cluster health counter; null when unavailable.", + "nullable": true, + "type": "integer" + }, + "pending": { + "description": "Pending and awaiting-reindex failed events, from at most 1000 backlog rows.", + "nullable": true, + "type": "integer" + }, + "replicaSettingsFailed": { + "description": "Sizing or applying the index replicas failed at startup; null when not attempted.", + "nullable": true, + "type": "boolean" + }, + "state": { + "description": "Overall availability; incomplete diagnostics are DEGRADED.", + "enum": [ + "OK", + "DEGRADED", + "DOWN", + "DISABLED" + ], + "nullable": false, + "type": "string" + }, + "tablesTruncated": { + "description": "More than 100 index rows exist.", + "nullable": false, + "type": "boolean" + }, + "targetReplicas": { + "description": "number_of_replicas Quick Search applies to its index; null when unknown or not managed (Serverless).", + "nullable": true, + "type": "integer" + }, + "unassignedReplicaShards": { + "description": "Unassigned shards when every primary is active (all are replicas); null when unknown or a primary is not active.", + "nullable": true, + "type": "integer" + }, + "unassignedShards": { + "description": "Cluster health counter; null when unavailable.", + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "QuickSearchSuggestGroupV1": { + "nullable": false, + "properties": { + "hasMore": { + "description": "An extra accessible item was found in the bounded batch. False does not prove the index has no further matches.", + "nullable": false, + "type": "boolean" + }, + "items": { + "description": "At most limitPerTable accessible items in per-table relevance order.", + "items": { + "$ref": "#/components/schemas/QuickSearchSuggestItemV1" + }, + "nullable": false, + "type": "array" + }, + "tableLabel": { + "description": "Source table label, falling back to its metadata name.", + "nullable": false, + "type": "string" + }, + "tableName": { + "description": "Source table metadata name.", + "nullable": false, + "type": "string" + } + }, + "type": "object" + }, + "QuickSearchSuggestItemV1": { + "nullable": false, + "properties": { + "label": { + "description": "Filtered record label, falling back to tableLabel #recordId when blank.", + "nullable": false, + "type": "string" + }, + "recordId": { + "description": "Source record primary key.", + "nullable": false, + "type": "string" + }, + "subtitle": { + "description": "Already-filtered result subtitle; null when absent.", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "QuickSearchSuggestV1": { + "nullable": false, + "properties": { + "groups": { + "description": "Readable tables ordered by best accessible score; at most maxTables.", + "items": { + "$ref": "#/components/schemas/QuickSearchSuggestGroupV1" + }, + "nullable": false, + "type": "array" + }, + "query": { + "description": "Search term after trimming and collapsing whitespace.", + "nullable": false, + "type": "string" + }, + "truncated": { + "description": "More tables had accessible hits than maxTables.", + "nullable": false, + "type": "boolean" + } + }, + "type": "object" + }, + "ReleaseNotesErrorV1": { + "properties": { + "error": { + "description": "What went wrong.", + "type": "string" + } + }, + "type": "object" + }, + "ReleaseNotesItemV1": { + "properties": { + "category": { + "description": "Item category.", + "enum": [ + "NEW", + "IMPROVED", + "FIXED", + "SECURITY", + "REMOVED" + ], + "type": "string" + }, + "categoryLabel": { + "description": "Category label, e.g. New.", + "type": "string" + }, + "linkUrl": { + "description": "Optional app path or https link.", + "nullable": true, + "type": "string" + }, + "screenshotUrl": { + "description": "Optional screenshot URL.", + "nullable": true, + "type": "string" + }, + "text": { + "description": "Customer-facing text.", + "type": "string" + } + }, + "type": "object" + }, + "ReleaseNotesLatestV1": { + "properties": { + "id": { + "description": "Release id.", + "type": "integer" + }, + "publishedAt": { + "description": "When it was published (ISO-8601).", + "type": "string" + }, + "title": { + "description": "Release title.", + "type": "string" + }, + "version": { + "description": "Application version.", + "type": "string" + } + }, + "type": "object" + }, + "ReleaseNotesReleaseV1": { + "properties": { + "id": { + "description": "Release id.", + "type": "integer" + }, + "isNew": { + "description": "Published after the user last looked.", + "type": "boolean" + }, + "items": { + "description": "Included items in category order.", + "items": { + "$ref": "#/components/schemas/ReleaseNotesItemV1" + }, + "type": "array" + }, + "publishedAt": { + "description": "When it was published (ISO-8601).", + "type": "string" + }, + "summary": { + "description": "Short summary.", + "nullable": true, + "type": "string" + }, + "title": { + "description": "Release title.", + "type": "string" + }, + "version": { + "description": "Application version.", + "type": "string" + } + }, + "type": "object" + }, + "ReleaseNotesReleasesV1": { + "properties": { + "lastSeenAt": { + "description": "When the user last marked What's new as seen.", + "nullable": true, + "type": "string" + }, + "releases": { + "description": "This page of releases, newest first.", + "items": { + "$ref": "#/components/schemas/ReleaseNotesReleaseV1" + }, + "type": "array" + }, + "total": { + "description": "Visible published releases.", + "type": "integer" + }, + "unreadCount": { + "description": "Releases new to the user.", + "type": "integer" + } + }, + "type": "object" + }, + "ReleaseNotesSeenV1": { + "properties": { + "unreadCount": { + "description": "Always 0 after marking seen.", + "type": "integer" + } + }, + "type": "object" + }, + "ReleaseNotesSummaryV1": { + "properties": { + "latest": { + "$ref": "#/components/schemas/ReleaseNotesLatestV1", + "description": "The newest visible release, or null.", + "nullable": true + }, + "unreadCount": { + "description": "Releases new to the user.", + "type": "integer" + } + }, + "type": "object" + }, + "SecuredDataBreakGlassV1": { + "properties": { + "id": { + "type": "integer" + }, + "reason": { + "type": "string" + }, + "expiresAt": { + "format": "date-time", + "type": "string" + }, + "scope": { + "nullable": true, + "type": "string" + }, + "ceiling": { + "type": "string" + } + }, + "type": "object" + }, + "SecuredDataErrorV1": { + "description": "Deprecated since 1.1.0: errors use BasicErrorResponseV1.", + "properties": { + "error": { + "type": "string" + } + }, + "type": "object" + }, + "SecuredDataRevealAllowanceV1": { + "properties": { + "tableName": { + "type": "string" + }, + "fieldName": { + "type": "string" + }, + "remainingDailyAllowance": { + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "SecuredDataRevealOptionsResponseV1": { + "properties": { + "reasonOptions": { + "items": { + "type": "string" + }, + "type": "array" + }, + "allowFreeTextReason": { + "type": "boolean" + }, + "requireFreeText": { + "type": "boolean" + }, + "revealMinutes": { + "type": "integer" + }, + "remainingDailyAllowance": { + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "SecuredDataRevealRequestV1": { + "description": "tableName, primaryKey and fieldName are required. Supply a policy reason or allowed free text; maximum 500 characters.", + "properties": { + "tableName": { + "type": "string" + }, + "fieldName": { + "type": "string" + }, + "primaryKey": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "description": "Record primary key (string or number)." + }, + "reason": { + "maxLength": 500, + "nullable": true, + "type": "string" + }, + "reasonText": { + "maxLength": 500, + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "SecuredDataRevealResponseV1": { + "properties": { + "value": { + "description": "Authorized raw field value.", + "nullable": true + }, + "displayValue": { + "nullable": true, + "type": "string" + }, + "expiresAt": { + "format": "date-time", + "type": "string" + }, + "revealId": { + "type": "integer" + } + }, + "type": "object" + }, + "SecuredDataStatusResponseV1": { + "properties": { + "breakGlass": { + "$ref": "#/components/schemas/SecuredDataBreakGlassV1", + "nullable": true + }, + "revealsUsedToday": { + "type": "integer" + }, + "revealAllowances": { + "items": { + "$ref": "#/components/schemas/SecuredDataRevealAllowanceV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "SqlWorkbenchBackendV1": { + "properties": { + "name": { + "type": "string" + }, + "label": { + "type": "string" + }, + "vendor": { + "nullable": true, + "type": "string" + }, + "dialect": { + "$ref": "#/components/schemas/SqlWorkbenchDialectV1" + }, + "readOnlyCredentials": { + "type": "boolean" + }, + "readOnlyEnforced": { + "type": "boolean" + }, + "transactionalDdl": { + "type": "boolean" + }, + "writeAllowed": { + "type": "boolean" + } + }, + "type": "object" + }, + "SqlWorkbenchBinaryValueV1": { + "properties": { + "$binary": { + "type": "boolean" + }, + "length": { + "format": "int64", + "type": "integer" + }, + "hexPreview": { + "type": "string" + } + }, + "type": "object" + }, + "SqlWorkbenchCancelledV1": { + "properties": { + "cancelled": { + "type": "boolean" + } + }, + "type": "object" + }, + "SqlWorkbenchCapabilitiesV1": { + "properties": { + "version": { + "type": "string" + }, + "canWrite": { + "type": "boolean" + }, + "canShare": { + "type": "boolean" + }, + "writeModeEnabled": { + "type": "boolean" + }, + "limits": { + "$ref": "#/components/schemas/SqlWorkbenchLimitsV1" + }, + "backends": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchBackendV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "SqlWorkbenchCellV1": { + "properties": { + "cellKey": { + "type": "string" + }, + "cellType": { + "type": "string" + }, + "title": { + "nullable": true, + "type": "string" + }, + "content": { + "type": "string" + }, + "backendName": { + "nullable": true, + "type": "string" + }, + "sortOrder": { + "format": "int64", + "type": "integer" + } + }, + "type": "object" + }, + "SqlWorkbenchColumnKindV1": { + "enum": [ + "number", + "string", + "boolean", + "date", + "datetime", + "time", + "json", + "binary", + "array", + "other" + ], + "type": "string" + }, + "SqlWorkbenchColumnV1": { + "properties": { + "name": { + "type": "string" + }, + "label": { + "type": "string" + }, + "typeName": { + "type": "string" + }, + "jdbcType": { + "format": "int64", + "type": "integer" + }, + "kind": { + "$ref": "#/components/schemas/SqlWorkbenchColumnKindV1" + } + }, + "type": "object" + }, + "SqlWorkbenchDatabaseSchemaV1": { + "properties": { + "name": { + "type": "string" + }, + "tables": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchSchemaTableV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "SqlWorkbenchDeletedV1": { + "properties": { + "deleted": { + "type": "boolean" + } + }, + "type": "object" + }, + "SqlWorkbenchDialectV1": { + "enum": [ + "postgresql", + "mysql", + "sqlite", + "h2", + "sql" + ], + "type": "string" + }, + "SqlWorkbenchEmptyRequestV1": { + "type": "object" + }, + "SqlWorkbenchErrorV1": { + "description": "Deprecated since 1.1.0: errors use BasicErrorResponseV1.", + "properties": { + "error": { + "type": "string" + } + }, + "type": "object" + }, + "SqlWorkbenchExecuteRequestV1": { + "properties": { + "backendName": { + "type": "string" + }, + "sql": { + "type": "string" + }, + "params": { + "$ref": "#/components/schemas/SqlWorkbenchParametersV1" + }, + "mode": { + "type": "string" + }, + "notebookId": { + "format": "int64", + "nullable": true, + "type": "integer" + }, + "cellKey": { + "nullable": true, + "type": "string" + }, + "pageSize": { + "format": "int64", + "nullable": true, + "type": "integer" + }, + "confirmToken": { + "nullable": true, + "type": "string" + }, + "acknowledgeRowGuard": { + "type": "boolean" + }, + "executionUuid": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "SqlWorkbenchExecutionV1": { + "properties": { + "executionUuid": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/SqlWorkbenchStatusV1" + }, + "mode": { + "type": "string" + }, + "backendName": { + "type": "string" + }, + "durationMs": { + "format": "int64", + "nullable": true, + "type": "integer" + }, + "statements": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchStatementV1" + }, + "type": "array" + }, + "columns": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchColumnV1" + }, + "type": "array" + }, + "rows": { + "$ref": "#/components/schemas/SqlWorkbenchRowsDataV1" + }, + "rowCount": { + "format": "int64", + "type": "integer" + }, + "hasMore": { + "type": "boolean" + }, + "truncated": { + "type": "boolean" + }, + "truncatedReason": { + "nullable": true, + "type": "string" + }, + "rowsAffected": { + "format": "int64", + "type": "integer" + }, + "error": { + "type": "string" + }, + "sqlState": { + "nullable": true, + "type": "string" + }, + "dryRunSupported": { + "type": "boolean" + }, + "dryRunNote": { + "nullable": true, + "type": "string" + }, + "totalAffectedRows": { + "format": "int64", + "nullable": true, + "type": "integer" + }, + "rowGuardExceeded": { + "type": "boolean" + }, + "rowGuardLimit": { + "format": "int64", + "type": "integer" + }, + "confirmToken": { + "type": "string" + }, + "expiresAt": { + "type": "string" + }, + "previewAffectedRows": { + "format": "int64", + "type": "integer" + }, + "actualAffectedRows": { + "format": "int64", + "type": "integer" + } + }, + "type": "object" + }, + "SqlWorkbenchExplainRequestV1": { + "properties": { + "backendName": { + "type": "string" + }, + "sql": { + "type": "string" + }, + "params": { + "$ref": "#/components/schemas/SqlWorkbenchParametersV1" + }, + "analyze": { + "type": "boolean" + } + }, + "type": "object" + }, + "SqlWorkbenchExplainV1": { + "properties": { + "executionUuid": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/SqlWorkbenchStatusV1" + }, + "mode": { + "type": "string" + }, + "backendName": { + "type": "string" + }, + "dialect": { + "$ref": "#/components/schemas/SqlWorkbenchDialectV1" + }, + "analyze": { + "type": "boolean" + }, + "plan": { + "$ref": "#/components/schemas/SqlWorkbenchPlanNodeV1" + }, + "raw": { + "type": "string" + }, + "error": { + "type": "string" + }, + "sqlState": { + "nullable": true, + "type": "string" + }, + "durationMs": { + "format": "int64", + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "SqlWorkbenchExportFileV1": { + "format": "binary", + "type": "string" + }, + "SqlWorkbenchExportJsonV1": { + "description": "Rows keyed by unique column labels, with duplicate labels suffixed.", + "items": { + "additionalProperties": { + "$ref": "#/components/schemas/SqlWorkbenchValueV1" + }, + "type": "object" + }, + "type": "array" + }, + "SqlWorkbenchFreeObjectV1": { + "additionalProperties": true, + "type": "object" + }, + "SqlWorkbenchHistoryEntryV1": { + "properties": { + "executionUuid": { + "type": "string" + }, + "backendName": { + "type": "string" + }, + "mode": { + "type": "string" + }, + "status": { + "type": "string" + }, + "sqlText": { + "type": "string" + }, + "notebookId": { + "format": "int64", + "nullable": true, + "type": "integer" + }, + "cellKey": { + "nullable": true, + "type": "string" + }, + "startTime": { + "nullable": true, + "type": "string" + }, + "durationMs": { + "format": "int64", + "nullable": true, + "type": "integer" + }, + "rowsReturned": { + "format": "int64", + "nullable": true, + "type": "integer" + }, + "rowsAffected": { + "format": "int64", + "nullable": true, + "type": "integer" + }, + "errorMessage": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "SqlWorkbenchHistoryV1": { + "properties": { + "executions": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchHistoryEntryV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "SqlWorkbenchLimitsV1": { + "properties": { + "maxRows": { + "format": "int64", + "type": "integer" + }, + "pageSize": { + "format": "int64", + "type": "integer" + }, + "maxPageSize": { + "format": "int64", + "type": "integer" + }, + "maxResultBytes": { + "format": "int64", + "type": "integer" + }, + "statementTimeoutSeconds": { + "format": "int64", + "type": "integer" + }, + "writeStatementTimeoutSeconds": { + "format": "int64", + "type": "integer" + }, + "maxAffectedRowsWithoutAcknowledgement": { + "format": "int64", + "type": "integer" + }, + "maxAffectedRows": { + "format": "int64", + "type": "integer" + }, + "maxSqlLength": { + "format": "int64", + "type": "integer" + }, + "maxStatementsPerRun": { + "format": "int64", + "type": "integer" + } + }, + "type": "object" + }, + "SqlWorkbenchNotebookContentV1": { + "properties": { + "title": { + "type": "string" + }, + "description": { + "nullable": true, + "type": "string" + }, + "defaultBackendName": { + "nullable": true, + "type": "string" + }, + "parameters": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchNotebookParameterV1" + }, + "type": "array" + }, + "cells": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchCellV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "SqlWorkbenchNotebookParameterV1": { + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "defaultValue": { + "nullable": true, + "type": "string" + }, + "label": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "SqlWorkbenchNotebookRequestV1": { + "properties": { + "title": { + "type": "string" + }, + "description": { + "nullable": true, + "type": "string" + }, + "defaultBackendName": { + "nullable": true, + "type": "string" + }, + "parameters": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchNotebookParameterV1" + }, + "type": "array" + }, + "cells": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchCellV1" + }, + "type": "array" + }, + "comment": { + "type": "string" + } + }, + "type": "object" + }, + "SqlWorkbenchNotebookSummaryV1": { + "properties": { + "id": { + "format": "int64", + "type": "integer" + }, + "title": { + "type": "string" + }, + "description": { + "nullable": true, + "type": "string" + }, + "visibility": { + "type": "string" + }, + "ownerUserId": { + "type": "string" + }, + "ownerName": { + "nullable": true, + "type": "string" + }, + "defaultBackendName": { + "nullable": true, + "type": "string" + }, + "currentVersion": { + "format": "int64", + "type": "integer" + }, + "canEdit": { + "type": "boolean" + }, + "createDate": { + "nullable": true, + "type": "string" + }, + "modifyDate": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "SqlWorkbenchNotebookV1": { + "properties": { + "id": { + "format": "int64", + "type": "integer" + }, + "title": { + "type": "string" + }, + "description": { + "nullable": true, + "type": "string" + }, + "visibility": { + "type": "string" + }, + "ownerUserId": { + "type": "string" + }, + "ownerName": { + "nullable": true, + "type": "string" + }, + "defaultBackendName": { + "nullable": true, + "type": "string" + }, + "currentVersion": { + "format": "int64", + "type": "integer" + }, + "canEdit": { + "type": "boolean" + }, + "createDate": { + "nullable": true, + "type": "string" + }, + "modifyDate": { + "nullable": true, + "type": "string" + }, + "parameters": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchNotebookParameterV1" + }, + "type": "array" + }, + "cells": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchCellV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "SqlWorkbenchNotebooksV1": { + "properties": { + "notebooks": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchNotebookSummaryV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "SqlWorkbenchParametersV1": { + "additionalProperties": {}, + "description": "Named SQL parameter values. JSON decimals are parsed exactly as BigDecimal.", + "type": "object" + }, + "SqlWorkbenchPlanNodeV1": { + "properties": { + "label": { + "type": "string" + }, + "detail": { + "nullable": true, + "type": "string" + }, + "startupCost": { + "nullable": true, + "type": "number" + }, + "totalCost": { + "nullable": true, + "type": "number" + }, + "planRows": { + "format": "int64", + "nullable": true, + "type": "integer" + }, + "actualTimeMs": { + "nullable": true, + "type": "number" + }, + "actualRows": { + "format": "int64", + "nullable": true, + "type": "integer" + }, + "loops": { + "format": "int64", + "nullable": true, + "type": "integer" + }, + "extra": { + "$ref": "#/components/schemas/SqlWorkbenchFreeObjectV1" + }, + "children": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchPlanNodeV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "SqlWorkbenchPublishRequestV1": { + "properties": { + "shared": { + "type": "boolean" + } + }, + "type": "object" + }, + "SqlWorkbenchQqqFieldV1": { + "properties": { + "name": { + "type": "string" + }, + "label": { + "nullable": true, + "type": "string" + }, + "sqlName": { + "type": "string" + }, + "type": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "SqlWorkbenchQqqTableV1": { + "properties": { + "name": { + "type": "string" + }, + "label": { + "nullable": true, + "type": "string" + }, + "sqlName": { + "type": "string" + }, + "fields": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchQqqFieldV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "SqlWorkbenchRowsDataV1": { + "items": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchValueV1" + }, + "type": "array" + }, + "type": "array" + }, + "SqlWorkbenchRowsV1": { + "properties": { + "executionUuid": { + "type": "string" + }, + "columns": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchColumnV1" + }, + "type": "array" + }, + "rows": { + "$ref": "#/components/schemas/SqlWorkbenchRowsDataV1" + }, + "offset": { + "format": "int64", + "type": "integer" + }, + "rowCount": { + "format": "int64", + "type": "integer" + }, + "truncated": { + "type": "boolean" + }, + "truncatedReason": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "SqlWorkbenchSchemaColumnV1": { + "properties": { + "name": { + "type": "string" + }, + "typeName": { + "type": "string" + }, + "nullable": { + "type": "boolean" + } + }, + "type": "object" + }, + "SqlWorkbenchSchemaTableV1": { + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "columns": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchSchemaColumnV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "SqlWorkbenchSchemaV1": { + "properties": { + "backendName": { + "type": "string" + }, + "dialect": { + "$ref": "#/components/schemas/SqlWorkbenchDialectV1" + }, + "schemas": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchDatabaseSchemaV1" + }, + "type": "array" + }, + "truncated": { + "type": "boolean" + }, + "keywords": { + "items": { + "type": "string" + }, + "type": "array" + }, + "functions": { + "items": { + "type": "string" + }, + "type": "array" + }, + "qqqTables": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchQqqTableV1" + }, + "type": "array" + }, + "cachedAt": { + "type": "string" + } + }, + "type": "object" + }, + "SqlWorkbenchSnapshotRequestV1": { + "properties": { + "executionUuid": { + "type": "string" + }, + "cellKey": { + "type": "string" + }, + "label": { + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "SqlWorkbenchSnapshotResultV1": { + "properties": { + "columns": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchColumnV1" + }, + "type": "array" + }, + "rows": { + "$ref": "#/components/schemas/SqlWorkbenchRowsDataV1" + } + }, + "type": "object" + }, + "SqlWorkbenchSnapshotV1": { + "properties": { + "id": { + "format": "int64", + "type": "integer" + }, + "cellKey": { + "nullable": true, + "type": "string" + }, + "executionUuid": { + "nullable": true, + "type": "string" + }, + "label": { + "nullable": true, + "type": "string" + }, + "backendName": { + "nullable": true, + "type": "string" + }, + "rowCount": { + "format": "int64", + "type": "integer" + }, + "truncated": { + "type": "boolean" + }, + "createDate": { + "nullable": true, + "type": "string" + }, + "result": { + "$ref": "#/components/schemas/SqlWorkbenchSnapshotResultV1" + } + }, + "type": "object" + }, + "SqlWorkbenchSnapshotsV1": { + "properties": { + "snapshots": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchSnapshotV1" + }, + "type": "array" + } + }, + "type": "object" + }, + "SqlWorkbenchStatementKindV1": { + "enum": [ + "READ", + "EXPLAIN_ANALYZE", + "WRITE", + "DDL", + "FORBIDDEN" + ], + "type": "string" + }, + "SqlWorkbenchStatementV1": { + "properties": { + "index": { + "format": "int64", + "type": "integer" + }, + "kind": { + "$ref": "#/components/schemas/SqlWorkbenchStatementKindV1" + }, + "leadingKeyword": { + "nullable": true, + "type": "string" + }, + "text": { + "type": "string" + }, + "affectedRows": { + "format": "int64", + "nullable": true, + "type": "integer" + } + }, + "type": "object" + }, + "SqlWorkbenchStatusV1": { + "enum": [ + "SUCCEEDED", + "FAILED", + "TIMED_OUT", + "CANCELLED", + "REJECTED", + "PREVIEW", + "DRIFTED" + ], + "type": "string" + }, + "SqlWorkbenchValueV1": { + "anyOf": [ + { + "nullable": true, + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "$ref": "#/components/schemas/SqlWorkbenchBinaryValueV1" + }, + { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchValueV1" + }, + "type": "array" + }, + { + "$ref": "#/components/schemas/SqlWorkbenchFreeObjectV1" + } + ], + "description": "JSON-safe JDBC value; null, scalar, binary preview, nested array or vendor JSON object." + }, + "SqlWorkbenchVersionSummaryV1": { + "properties": { + "versionNumber": { + "format": "int64", + "type": "integer" + }, + "savedByName": { + "nullable": true, + "type": "string" + }, + "comment": { + "nullable": true, + "type": "string" + }, + "createDate": { + "type": "string" + } + }, + "type": "object" + }, + "SqlWorkbenchVersionV1": { + "properties": { + "versionNumber": { + "format": "int64", + "type": "integer" + }, + "savedByName": { + "nullable": true, + "type": "string" + }, + "comment": { + "nullable": true, + "type": "string" + }, + "createDate": { + "type": "string" + }, + "notebook": { + "$ref": "#/components/schemas/SqlWorkbenchNotebookContentV1" + } + }, + "type": "object" + }, + "SqlWorkbenchVersionsV1": { + "properties": { + "versions": { + "items": { + "$ref": "#/components/schemas/SqlWorkbenchVersionSummaryV1" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "securitySchemes": { + "sessionUuidCookie": { + "type": "apiKey", + "name": "sessionUUID", + "in": "cookie", + "description": "The session cookie set by POST /qqq/v1/manageSession (web clients)." + }, + "bearerAuth": { + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT or session UUID", + "description": "`Authorization: Bearer `, where the token is either\n- an OAuth2 access token (a signed JWT) issued by the app's identity provider to the app's client,\n or to its native client (`values.nativeClientId` in GET /qqq/v1/metaData/authentication), for\n example from the device-authorization grant or auth-code + PKCE. It is verified against the\n provider's keys (issuer, audience, expiry, signature) and gives the same user and permissions\n as signing in on the web. When it expires (401), refresh it at the provider and retry; or\n- a session UUID returned by POST /qqq/v1/manageSession, which the server keeps refreshed." + }, + "oauth2": { + "type": "oauth2", + "description": "The app's OAuth2 / OpenID Connect provider. The real endpoints come from the provider's discovery\ndocument: `{values.baseUrl}.well-known/openid-configuration`, with values from\nGET /qqq/v1/metaData/authentication. Native clients use `values.nativeClientId` (a public client)\nwith auth-code + PKCE (loopback or custom-scheme redirect URI registered at the provider) or the\ndevice-authorization grant (`device_authorization_endpoint`, RFC 8628), then send the access token\nas `Authorization: Bearer`.", + "flows": { + "authorizationCode": { + "authorizationUrl": "/authorize", + "tokenUrl": "/token", + "scopes": { + "email": "Email address", + "offline_access": "A refresh token, to renew the access token without signing in again", + "openid": "OpenID Connect sign-in", + "profile": "Name, username and groups (permissions come from the groups)" + } + } + } + } + } + } +} diff --git a/packages/ui-api-client/src/schema.ts b/packages/ui-api-client/src/schema.ts index 85195c0..f77831d 100644 --- a/packages/ui-api-client/src/schema.ts +++ b/packages/ui-api-client/src/schema.ts @@ -1492,6 +1492,2265 @@ export interface paths { patch?: never; trace?: never; }; + "/qqq/v1/health/summary": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Health summary + * @description Requires health.read permission. Returns redacted health state. + */ + get: operations["getHealthSummary"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/health/components/{name}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Health component + * @description Requires health.read permission. Returns redacted health state. + */ + get: operations["getHealthComponentsByName"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/health/checks/{name}/history": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Health history + * @description Requires health.read permission. Returns redacted health state. + */ + get: operations["getHealthChecksByNameHistory"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/health/checks/{name}/run": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Health run + * @description Requires health.write permission. Returns redacted health state. + */ + post: operations["postHealthChecksByNameRun"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/alerts/inbox/summary": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Read the bell summary + * @description Uses the signed-in caller's permissions and record visibility. + */ + get: operations["alertsInboxSummary"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/alerts/inbox": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Page the notification inbox + * @description Uses the signed-in caller's permissions and record visibility. + */ + get: operations["alertsInbox"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/alerts/inbox/read": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Mark own notifications read + * @description Uses the signed-in caller's permissions and record visibility. + */ + post: operations["alertsInboxRead"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/alerts/inbox/unread": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Mark own notifications unread + * @description Uses the signed-in caller's permissions and record visibility. + */ + post: operations["alertsInboxUnread"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/alerts/inbox/dismiss": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Dismiss own notifications + * @description Uses the signed-in caller's permissions and record visibility. + */ + post: operations["alertsInboxDismiss"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/alerts/record-panel": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Read visible alerts for a record + * @description Uses the signed-in caller's permissions and record visibility. + */ + get: operations["alertsRecordPanel"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/assistant/config": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Whether the assistant is available to this user, its persona and limits + * @description Whether the assistant is available to this user, its persona and limits + */ + get: operations["getAssistantConfig"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/assistant/conversations": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * The user's own conversations + * @description The user's own conversations + */ + get: operations["getAssistantConversations"]; + put?: never; + /** + * Start a conversation + * @description Start a conversation + */ + post: operations["postAssistantConversations"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/assistant/conversations/{id}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * A conversation and a page of its messages + * @description A conversation and a page of its messages + */ + get: operations["getAssistantConversationsById"]; + put?: never; + post?: never; + /** + * Delete a conversation + * @description Delete a conversation + */ + delete: operations["deleteAssistantConversationsById"]; + options?: never; + head?: never; + /** + * Rename, pin, archive or mark read a conversation + * @description Rename, pin, archive or mark read a conversation + */ + patch: operations["patchAssistantConversationsById"]; + trace?: never; + }; + "/qqq/v1/assistant/conversations/{id}/turns": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Ask: start a turn and stream the reply as server-sent events + * @description Ask: start a turn and stream the reply as server-sent events + */ + post: operations["postAssistantConversationsByIdTurns"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/assistant/turns/{turnId}/events": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Resume a turn's events after a sequence number (replay, then the live tail) + * @description Resume a turn's events after a sequence number (replay, then the live tail) + */ + get: operations["getAssistantTurnsByTurnIdEvents"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/assistant/turns/{turnId}/cancel": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Stop a running turn + * @description Stop a running turn + */ + post: operations["postAssistantTurnsByTurnIdCancel"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/assistant/turns/active": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Find the user's active assistant runs + * @description Find the user's active assistant runs + */ + get: operations["getAssistantTurnsActive"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/assistant/messages/{id}/feedback": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Thumbs up or down on an assistant message + * @description Thumbs up or down on an assistant message + */ + post: operations["postAssistantMessagesByIdFeedback"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/assistant/actions/{id}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * A write the assistant proposed, and its state + * @description A write the assistant proposed, and its state + */ + get: operations["getAssistantActionsById"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/assistant/actions/{id}/confirm": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Confirm a proposed write: it runs once, through the UI API, with this request's session + * @description Confirm a proposed write: it runs once, through the UI API, with this request's session + */ + post: operations["postAssistantActionsByIdConfirm"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/assistant/actions/{id}/reject": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Cancel a proposed write; nothing changes + * @description Cancel a proposed write; nothing changes + */ + post: operations["postAssistantActionsByIdReject"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/assistant/access": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Explain access: which UI API operations the assistant could call for this user, and why not + * @description Explain access: which UI API operations the assistant could call for this user, and why not + */ + get: operations["getAssistantAccess"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/assistant/client-errors": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Report an error the client hit while showing the assistant (stored for administrators, rate limited per user) + * @description Report an error the client hit while showing the assistant (stored for administrators, rate limited per user) + */ + post: operations["postAssistantClientErrors"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/presence": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get presence snapshot + * @description Get presence snapshot. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationPresence"]; + put?: never; + /** + * Renew presence + * @description Renew presence. Uses the signed-in caller's permissions and record visibility. + */ + post: operations["postQbitCollaborationPresence"]; + /** + * Leave presence + * @description Leave presence. Uses the signed-in caller's permissions and record visibility. + */ + delete: operations["deleteQbitCollaborationPresence"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/favorites": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List personal favorites + * @description List personal favorites. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationFavorites"]; + /** + * Star a target + * @description Star a target. Uses the signed-in caller's permissions and record visibility. + */ + put: operations["putQbitCollaborationFavorites"]; + post?: never; + /** + * Unstar a target + * @description Unstar a target. Uses the signed-in caller's permissions and record visibility. + */ + delete: operations["deleteQbitCollaborationFavorites"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/recents": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List recent targets + * @description List recent targets. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationRecents"]; + put?: never; + /** + * Record a recent view + * @description Record a recent view. Uses the signed-in caller's permissions and record visibility. + */ + post: operations["postQbitCollaborationRecents"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/favorites/order": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + /** + * Reorder personal favorites + * @description Reorder personal favorites. Uses the signed-in caller's permissions and record visibility. + */ + patch: operations["patchQbitCollaborationFavoritesOrder"]; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/attachments": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List record attachments + * @description List record attachments. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationRecordsByTableByPkAttachments"]; + put?: never; + /** + * Upload an attachment + * @description Upload an attachment. Uses the signed-in caller's permissions and record visibility. + */ + post: operations["postQbitCollaborationRecordsByTableByPkAttachments"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/attachments/{id}/download": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get a temporary download URL; clients follow url + * @description Get a temporary download URL; clients follow url. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationAttachmentsByIdDownload"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/attachments/{id}/preview": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get a temporary preview URL; clients follow url + * @description Get a temporary preview URL; clients follow url. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationAttachmentsByIdPreview"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/attachments/{id}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** + * Delete an attachment + * @description Delete an attachment. Uses the signed-in caller's permissions and record visibility. + */ + delete: operations["deleteQbitCollaborationAttachmentsById"]; + options?: never; + head?: never; + /** + * Rename or describe an attachment + * @description Rename or describe an attachment. Uses the signed-in caller's permissions and record visibility. + */ + patch: operations["patchQbitCollaborationAttachmentsById"]; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/tags": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Search table tag vocabulary + * @description Search table tag vocabulary. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationTags"]; + put?: never; + /** + * Create or suggest a tag + * @description Create or suggest a tag. Uses the signed-in caller's permissions and record visibility. + */ + post: operations["postQbitCollaborationTags"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/tags": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List applied record tags + * @description List applied record tags. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationRecordsByTableByPkTags"]; + /** + * Add and remove record tags + * @description Add and remove record tags. Uses the signed-in caller's permissions and record visibility. + */ + put: operations["putQbitCollaborationRecordsByTableByPkTags"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/comments": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Page record comment threads + * @description Page record comment threads. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationRecordsByTableByPkComments"]; + put?: never; + /** + * Post a comment or reply + * @description Post a comment or reply. Uses the signed-in caller's permissions and record visibility. + */ + post: operations["postQbitCollaborationRecordsByTableByPkComments"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/comments/{id}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** + * Delete a comment thread + * @description Delete a comment thread. Uses the signed-in caller's permissions and record visibility. + */ + delete: operations["deleteQbitCollaborationCommentsById"]; + options?: never; + head?: never; + /** + * Edit the caller's comment + * @description Edit the caller's comment. Uses the signed-in caller's permissions and record visibility. + */ + patch: operations["patchQbitCollaborationCommentsById"]; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/comments/{id}/resolve": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Resolve a comment thread + * @description Resolve a comment thread. Uses the signed-in caller's permissions and record visibility. + */ + post: operations["postQbitCollaborationCommentsByIdResolve"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/comments/{id}/reopen": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Reopen a comment thread + * @description Reopen a comment thread. Uses the signed-in caller's permissions and record visibility. + */ + post: operations["postQbitCollaborationCommentsByIdReopen"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/comments/{id}/history": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Read comment edit history + * @description Read comment edit history. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationCommentsByIdHistory"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/mentions/candidates": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Find people to mention on a record + * @description Find people to mention on a record. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationMentionsCandidates"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/follow": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get the caller's follow state + * @description Get the caller's follow state. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationRecordsByTableByPkFollow"]; + /** + * Follow a record and configure notifications + * @description Follow a record and configure notifications. Uses the signed-in caller's permissions and record visibility. + */ + put: operations["putQbitCollaborationRecordsByTableByPkFollow"]; + post?: never; + /** + * Unfollow a record + * @description Unfollow a record. Uses the signed-in caller's permissions and record visibility. + */ + delete: operations["deleteQbitCollaborationRecordsByTableByPkFollow"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/followers": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List record followers + * @description List record followers. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationRecordsByTableByPkFollowers"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/timeline": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Page the merged record timeline + * @description Page the merged record timeline. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationRecordsByTableByPkTimeline"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/people": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Search the active people directory + * @description Search the active people directory. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationPeople"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/people/{userId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get an active directory person + * @description Get an active directory person. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationPeopleByUserId"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/link": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get a record link + * @description Get a record link. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationRecordsByTableByPkLink"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/shares/preview": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Preview share recipients + * @description Preview share recipients. Uses the signed-in caller's permissions and record visibility. + */ + post: operations["postQbitCollaborationRecordsByTableByPkSharesPreview"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/shares": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Share a record + * @description Share a record. Uses the signed-in caller's permissions and record visibility. + */ + post: operations["postQbitCollaborationRecordsByTableByPkShares"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/access-requests": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Request access to a record + * @description Request access to a record. Uses the signed-in caller's permissions and record visibility. + */ + post: operations["postQbitCollaborationAccessRequests"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/access-requests/mine": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List my access requests + * @description List my access requests. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationAccessRequestsMine"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/tasks": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List record tasks + * @description List record tasks. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationRecordsByTableByPkTasks"]; + put?: never; + /** + * Create a task + * @description Create a task. Uses the signed-in caller's permissions and record visibility. + */ + post: operations["postQbitCollaborationRecordsByTableByPkTasks"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/tasks/{id}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + /** + * Update a task + * @description Update a task. Uses the signed-in caller's permissions and record visibility. + */ + patch: operations["patchQbitCollaborationTasksById"]; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/tasks/mine": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List my tasks + * @description List my tasks. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationTasksMine"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/records/{table}/{pk}/assignment": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * Set record owner and assignee + * @description Set record owner and assignee. Uses the signed-in caller's permissions and record visibility. + */ + put: operations["putQbitCollaborationRecordsByTableByPkAssignment"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/collaboration/my-work": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get my work summary + * @description Get my work summary. Uses the signed-in caller's permissions and record visibility. + */ + get: operations["getQbitCollaborationMyWork"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/saved/{id}/run": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Run a saved analysis + * @description Re-run a visible saved analysis as the signed-in viewer. Requires saved READ and source READ/Analyze. Drops unavailable fields with a warning and returns the result typed by kind; inaccessible required axes or predicates produce no result. + */ + post: operations["postQbitDataAnalysisSavedByIdRun"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/saved": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List visible saved analyses + * @description List core-visible saved analyses with name, kind, source table label, owner, shared state, this viewer's starred flag and last update. + */ + get: operations["getQbitDataAnalysisSaved"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/saved/{id}/star": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * Star a saved analysis + * @description Star a visible saved analysis for the signed-in user. Idempotent; uses standard saved insert permission and the personal star record lock. + */ + put: operations["putQbitDataAnalysisSavedByIdStar"]; + post?: never; + /** + * Unstar a saved analysis + * @description Remove the signed-in user's star on a visible saved analysis. Idempotent; uses standard saved delete permission and owner locks. + */ + delete: operations["deleteQbitDataAnalysisSavedByIdStar"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/tables/{table}/sql": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Read an analysis aggregate SQL statement + * @description Execute a typed analysis as the viewer and capture the main RDBMS aggregate SQL from core QueryStat. Requires installed SQL Workbench and its access permission. Non-RDBMS backends report unavailable; SQL is for reading and record security remains enforced at runtime. + */ + post: operations["postQbitDataAnalysisTablesByTableSql"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/export": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Export an analysis result + * @description Execute a typed analysis as the signed-in viewer and download its result table as CSV or XLSX. Requires source READ/Analyze and FULL fields; uses core report formats. + */ + post: operations["postQbitDataAnalysisExport"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/saved/{id}/export": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Export a saved analysis + * @description Re-run a visible saved analysis as the viewer, applying current source permissions and dropping unavailable fields, then download its result table as CSV or XLSX. + */ + get: operations["getQbitDataAnalysisSavedByIdExport"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/tables/{table}/capabilities": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Check analysis availability + * @description Discover whether the current user can analyze this table, readable fields, chart defaults, limits and backend capabilities. + */ + get: operations["getQbitDataAnalysisTablesByTableCapabilities"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/tables/{table}/column-profile": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Profile one column + * @description Profile one column of a table under a filter: counts, nulls, distinct values, top values, numeric statistics and histogram, date patterns; every number has a drill-through filter unless privacy suppresses it. + */ + post: operations["postQbitDataAnalysisTablesByTableColumnProfile"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/tables/{table}/distinct-values": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * List distinct column values + * @description Page through distinct stored values with display labels, counts and drill-through filters; search narrows stored values. + */ + post: operations["postQbitDataAnalysisTablesByTableDistinctValues"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/tables/{table}/compare": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Compare two populations + * @description Compare filtered A with filtered B (null means the whole permitted table). Return means, medians or category shares, B-minus-A deltas, valid significance tests and count-equivalent drills. Only FULL fields are accepted. + */ + post: operations["postQbitDataAnalysisTablesByTableCompare"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/tables/{table}/shift": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Measure distribution shift over time + * @description Compare category shares or numeric quartiles across session-timezone calendar buckets. Compute descriptive PSI between the first and last complete nonempty buckets using fixed categories or baseline quartile bins. + */ + post: operations["postQbitDataAnalysisTablesByTableShift"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/tables/{table}/correlation": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Find numeric relationships + * @description Compute a Pearson correlation matrix for 2 to 12 distinct FULL numeric fields, using paired non-null records. Every cell includes n and parameters for the scatter endpoint; core pushes down CORR or uses bounded streaming. + */ + post: operations["postQbitDataAnalysisTablesByTableCorrelation"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/tables/{table}/scatter": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Inspect a numeric relationship + * @description Return at most 2000 paired numeric points as the user, ordered by primary key when core query sampling is unavailable, plus a least-squares line fitted to the sample. Privacy disables individual drills and suppresses small populations. + */ + post: operations["postQbitDataAnalysisTablesByTableScatter"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/tables/{table}/crosstab": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Cross-tabulate two fields + * @description Count combinations of two FULL fields with row and column shares, up to 20 categories per axis plus Other. Test independence using chi-square and Cramer V after pooling low expected counts; privacy suppresses small cells and their drills. + */ + post: operations["postQbitDataAnalysisTablesByTableCrosstab"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/watches/{id}/preview": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Preview an anomaly watch + * @description Compute complete time buckets and a detector verdict under the signed-in user's READ, Analyze and FULL-field permissions. Includes a baseline band annotation. Does not update the watch or raise alerts. + */ + post: operations["postQbitDataAnalysisWatchesByIdPreview"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/tables/{table}/pivot": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Explore a pivot table + * @description Group records by up to 3 row and 2 column fields (with date or numeric buckets) and compute counts, sums, averages, min/max, distinct counts or percentiles per cell; every cell has a drill-through filter. + */ + post: operations["postQbitDataAnalysisTablesByTablePivot"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/tables/{table}/table-profile": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Profile table completeness and keys + * @description Profile readable fields under a filter for completeness, uniqueness, constant or empty columns and candidate keys. + */ + post: operations["postQbitDataAnalysisTablesByTableTableProfile"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/tables/{table}/duplicates": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Find duplicate groups + * @description Group matching records by the selected readable fields and return repeated tuples with counts and drill-through filters. + */ + post: operations["postQbitDataAnalysisTablesByTableDuplicates"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/runs": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Start an exact profile run + * @description Start an owner-scoped exact column or table profile. Poll the returned runId until COMPLETE or FAILED; results honor the current session permissions. + */ + post: operations["postQbitDataAnalysisRuns"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/data-analysis/runs/{runId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get an exact profile run + * @description Read status, timestamps and the typed columnProfile or tableProfile result of an owner-scoped run. Completed results are rechecked against current permissions. + */ + get: operations["getQbitDataAnalysisRunsByRunId"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/db-performance/overview": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Database Performance overview + * @description Requires db_performance.view and uses the caller's session. + */ + get: operations["dbPerformanceOverview"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/db-performance/activity": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Database Performance activity + * @description Requires db_performance.view and uses the caller's session. + */ + get: operations["dbPerformanceActivity"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/db-performance/explain": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Explain a PostgreSQL query + * @description PLAN requires db_performance.explain; ANALYZE requires db_performance.explain_analyze. Values and ANALYZE plans are never persisted. + */ + post: operations["dbPerformanceExplain"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/db-performance/statements/lookup": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Database Performance lookup + * @description Requires db_performance.view and uses the caller's session. + */ + get: operations["dbPerformanceLookup"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/edi/guides/{guideId}/tree": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Read the guide tree + * @description Read the guide tree. Uses the caller session and table read permissions. Preview also requires edi.map.preview. Rule writes use core table CRUD. + */ + get: operations["getQbitEdiGuidesByGuideIdTree"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/edi/maps/{mapId}/target": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Read target metadata and map rules + * @description Read target metadata and map rules. Uses the caller session and table read permissions. Preview also requires edi.map.preview. Rule writes use core table CRUD. + */ + get: operations["getQbitEdiMapsByMapIdTarget"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/edi/sandbox/preview": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Preview an encrypted sample with optional unsaved rules + * @description Preview an encrypted sample with optional unsaved rules. Uses the caller session and table read permissions. Preview also requires edi.map.preview. Rule writes use core table CRUD. + */ + post: operations["postQbitEdiSandboxPreview"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/edi/maps/{mapId}/validate": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Validate unsaved map rules + * @description Validate unsaved map rules. Uses the caller session and table read permissions. Preview also requires edi.map.preview. Rule writes use core table CRUD. + */ + post: operations["postQbitEdiMapsByMapIdValidate"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/qa-capture/capability": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Read the QA capture capability + * @description Whether QA capture is on for the signed-in user and why, the provider settings, sanitizer rules, blur selectors, Content-Security-Policy origins and server context. Requires a session; a user without access gets enabled=false, never 403. + */ + get: operations["qaCaptureCapability"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/qa-capture/report": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Create a QA report + * @description Stores the report (page, app, table, record, process, recent request ids, client build) with the user, environment, backend version, node and provider filled in by the server, and returns its reference and the recorder parameters. + */ + post: operations["qaCaptureReportCreate"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/quick-search/status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get Quick Search status + * @description Requires Quick Search admin permission. Five-second instance cache; two-second refresh wait. Counts are saved diagnostics, not live source scans. Unknown values are null. Backlog counts are lower bounds when backlogTruncated is true. + */ + get: operations["getQuickSearchStatus"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/quick-search/suggest": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get Quick Search suggestions + * @description Requires a signed-in session, not Quick Search admin permission. Results inherit table READ permissions, configured record security locks and protected-field exclusions. One bounded candidate batch per table; no extra scans. Unavailable search and normalized terms shorter than two characters return empty groups. + */ + get: operations["getQuickSearchSuggestions"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/release-notes/releases": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Published release notes + * @description Published releases visible to the signed-in user, newest first, with their customer-facing items and whether each is new to the user. + */ + get: operations["releaseNotesReleases"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/release-notes/summary": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * What's new summary + * @description How many published releases are new to the signed-in user, and the latest one, for a menu badge. + */ + get: operations["releaseNotesSummary"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/release-notes/seen": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Mark What's new as seen + * @description Clears the signed-in user's new indicator. Takes no body. + */ + post: operations["releaseNotesSeen"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/secured-data/reveal": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Reveal */ + post: operations["postQbitSecuredDataReveal"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/secured-data/reveal/options": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** RevealOptions */ + get: operations["getQbitSecuredDataRevealOptions"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/qbit/secured-data/status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Status */ + get: operations["getQbitSecuredDataStatus"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/capabilities": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get caller capabilities and configured limits + * @description Get caller capabilities and configured limits. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + get: operations["sqlWorkbenchGetCapabilities"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/schema/{backendName}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Inspect a target backend schema + * @description Inspect a target backend schema. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + get: operations["sqlWorkbenchGetSchema"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/execute": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Execute read-only SQL or preview and confirm a gated write + * @description Execute read-only SQL or preview and confirm a gated write. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + post: operations["sqlWorkbenchExecute"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/explain": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Explain SQL; ANALYZE remains subject to write gates + * @description Explain SQL; ANALYZE remains subject to write gates. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + post: operations["sqlWorkbenchExplain"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/executions/{uuid}/rows": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Page or sort the caller's cached result + * @description Page or sort the caller's cached result. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + get: operations["sqlWorkbenchGetRows"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/executions/{uuid}/cancel": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Cancel the caller's running execution + * @description Cancel the caller's running execution. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + post: operations["sqlWorkbenchCancelExecution"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/history": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List the caller's recent audited executions + * @description List the caller's recent audited executions. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + get: operations["sqlWorkbenchGetHistory"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/notebooks": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List visible personal or shared notebooks + * @description List visible personal or shared notebooks. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + get: operations["sqlWorkbenchListNotebooks"]; + put?: never; + /** + * Create a personal notebook + * @description Create a personal notebook. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + post: operations["sqlWorkbenchCreateNotebook"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/notebooks/{id}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get a visible notebook and its cells + * @description Get a visible notebook and its cells. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + get: operations["sqlWorkbenchGetNotebook"]; + /** + * Update an owned notebook and record a version + * @description Update an owned notebook and record a version. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + put: operations["sqlWorkbenchUpdateNotebook"]; + post?: never; + /** + * Delete an owned notebook + * @description Delete an owned notebook. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + delete: operations["sqlWorkbenchDeleteNotebook"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/notebooks/{id}/publish": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Publish or withdraw an owned notebook with share permission + * @description Publish or withdraw an owned notebook with share permission. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + post: operations["sqlWorkbenchPublishNotebook"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/notebooks/{id}/duplicate": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Make a personal copy of a visible notebook + * @description Make a personal copy of a visible notebook. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + post: operations["sqlWorkbenchDuplicateNotebook"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/notebooks/{id}/versions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List versions of a visible notebook + * @description List versions of a visible notebook. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + get: operations["sqlWorkbenchListVersions"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/notebooks/{id}/versions/{n}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get a visible notebook version and saved content + * @description Get a visible notebook version and saved content. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + get: operations["sqlWorkbenchGetVersion"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/notebooks/{id}/versions/{n}/restore": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Restore an owned notebook version as a new version + * @description Restore an owned notebook version as a new version. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + post: operations["sqlWorkbenchRestoreVersion"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/notebooks/{id}/snapshots": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List snapshots of a visible notebook + * @description List snapshots of a visible notebook. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + get: operations["sqlWorkbenchListSnapshots"]; + put?: never; + /** + * Pin the caller's cached result to an owned notebook + * @description Pin the caller's cached result to an owned notebook. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + post: operations["sqlWorkbenchCreateSnapshot"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/notebooks/{id}/snapshots/{snapshotId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** + * Delete a snapshot from an owned notebook + * @description Delete a snapshot from an owned notebook. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + delete: operations["sqlWorkbenchDeleteSnapshot"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/qqq/v1/sql-workbench/executions/{uuid}/export": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Export the caller's cached result as CSV, JSON or XLSX + * @description Export the caller's cached result as CSV, JSON or XLSX. Requires SQL Workbench access; services enforce caller permissions, ownership, execution limits and audit. + */ + get: operations["sqlWorkbenchExportResult"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; } export type webhooks = Record; export interface components { @@ -5569,6 +7828,2746 @@ export interface components { /** @description Widget data object, whose shape varies by widget type. */ widgetData?: Record; }; + HealthCheckV1: { + name?: string | null; + label?: string | null; + kind?: string | null; + severity?: string | null; + currentStatus?: string | null; + currentMessage?: string | null; + currentSince?: string | null; + lastRunAt?: string | null; + lastLatencyMs?: number | null; + }; + HealthComponentV1: { + name?: string | null; + label?: string | null; + status?: string | null; + since?: string | null; + checksUp?: number | null; + checksDegraded?: number | null; + checksDown?: number | null; + checksUnknown?: number | null; + worstCheckId?: number | null; + updatedAt?: string | null; + checks?: components["schemas"]["HealthCheckV1"][]; + }; + HealthCountsV1: { + up?: number | null; + degraded?: number | null; + down?: number | null; + unknown?: number | null; + }; + HealthDetailsV1: { + values?: { + [key: string]: unknown; + }; + }; + HealthHistoryV1: { + results?: components["schemas"]["HealthResultV1"][]; + }; + HealthMetricV1: { + name?: string | null; + value?: number; + unit?: string | null; + }; + HealthResultV1: { + id?: number | null; + status?: string | null; + message?: string | null; + detailsJson?: string | null; + metricsJson?: string | null; + latencyMs?: number | null; + startedAt?: string | null; + finishedAt?: string | null; + runnerPod?: string | null; + isTransition?: boolean; + triggeredBy?: string | null; + }; + HealthRunV1: { + status?: string | null; + message?: string | null; + details?: components["schemas"]["HealthDetailsV1"]; + latencyMs?: number | null; + metrics?: components["schemas"]["HealthMetricV1"][]; + }; + HealthRunnerV1: { + lastBeatAt?: string | null; + pods?: (string | null)[]; + }; + HealthSummaryV1: { + status?: string | null; + since?: string | null; + counts?: components["schemas"]["HealthCountsV1"]; + components?: components["schemas"]["HealthComponentV1"][]; + runner?: components["schemas"]["HealthRunnerV1"]; + }; + /** @description An available action: operationId targets an inbox operation with this item id; process actions provide a complete href. */ + AlertsActionV1: { + href?: string; + label?: string; + name?: string; + operationId?: string; + processName?: string; + }; + /** @description Deprecated since 1.2.0: errors use BasicErrorResponseV1. */ + AlertsErrorV1: { + error?: string | null; + }; + /** @description Capability discovery only. Next obtains the follow URL from its collaboration module. */ + AlertsFollowV1: { + /** @description True exactly when the collaboration UI API extension is registered. */ + available?: boolean; + }; + /** @description A notification recipient. body is included only in page items and banners; alertId only for ALERT notifications. */ + AlertsInboxItemV1: { + actions?: components["schemas"]["AlertsActionV1"][]; + age?: string; + alertId?: number | null; + body?: string | null; + category?: string | null; + deliveredAt?: string | null; + /** @description Existing safe link, or null. */ + href?: string | null; + id?: number; + linkLabel?: string | null; + notificationId?: number; + severity?: string | null; + source?: string | null; + sticky?: boolean; + title?: string | null; + unread?: boolean; + }; + /** @description Filtered notification page. */ + AlertsInboxPageV1: { + items?: components["schemas"]["AlertsInboxItemV1"][]; + limit?: number; + offset?: number; + total?: number; + }; + /** @description Bell summary, latest ten items and up to three sticky banners. */ + AlertsInboxSummaryV1: { + alertsHref?: string; + banners?: components["schemas"]["AlertsInboxItemV1"][]; + highestUnreadSeverity?: string | null; + /** @description Canonical inbox navigation link. */ + inboxHref?: string; + items?: components["schemas"]["AlertsInboxItemV1"][]; + /** @description Existing notifications page link; retained for compatibility. */ + notificationsHref?: string; + pollSeconds?: number; + /** @description Name of the user Preferences section for notification settings (/qqq/v1/preferences/{name}), or null when not registered. */ + preferencesSection?: string | null; + unreadCount?: number; + }; + /** @description Select id, nonempty ids (first 500), legacy alertId, or all:true in that precedence. All scans are capped at 1000 rows. */ + AlertsInboxTargetV1: { + alertId?: number; + all?: boolean; + id?: number; + ids?: number[]; + }; + /** @description Number of the caller own recipient rows changed. */ + AlertsMutationResultV1: { + updated?: number; + }; + /** @description A visible open alert with permission-aware process actions. */ + AlertsPanelAlertV1: { + actions?: components["schemas"]["AlertsActionV1"][]; + age?: string; + alertId?: number; + group?: string | null; + href?: string; + raisedAt?: string | null; + severity?: string | null; + status?: string | null; + title?: string | null; + }; + /** @description Open alerts, recent resolutions and collaboration capability. watching is deprecated legacy subscription state. */ + AlertsRecordPanelV1: { + canManage?: boolean; + follow?: components["schemas"]["AlertsFollowV1"]; + open?: components["schemas"]["AlertsPanelAlertV1"][]; + openCount?: number; + resolvedLast30Days?: number; + viewAllHref?: string | null; + visible?: boolean; + /** @description Deprecated: existing RECORD subscriptions only; does not represent collaboration follow state. */ + watching?: boolean; + }; + /** @description Select id or nonempty ids (first 500), in that precedence. Legacy alertId is also accepted for compatibility. all is not supported. */ + AlertsUnreadTargetV1: { + alertId?: number; + id?: number; + ids?: number[]; + }; + /** @description Explain access: per table, the user's UI permissions, the assistant's data access, and each tool's verdict. */ + AssistantAccessResponseV1: { + tables?: { + [key: string]: unknown; + }[]; + }; + /** @description A write the assistant proposed and its state. */ + AssistantActionV1: { + id?: number; + /** @description PENDING, RUNNING, EXECUTED, FAILED, REJECTED or EXPIRED. */ + status?: string; + toolName?: string; + tableName?: string; + recordId?: string | null; + summary?: string; + /** @description The UI API status of the write. */ + httpStatus?: number | null; + resultSummary?: string | null; + expiresAt?: string | null; + /** @description After a confirm: the tool outcome. */ + outcome?: string | null; + /** @description After a confirm: what happened. */ + message?: string | null; + /** @description After a confirm: the written record's /app link. */ + href?: string | null; + }; + /** @description The caller's active runs, newest first; stale leases are reaped. */ + AssistantActiveTurnsResponseV1: { + turns?: { + turnId?: number; + conversationId?: number; + assistantMessageId?: number; + userMessageId?: number; + /** @description RUNNING or CANCELLING. */ + status?: string; + phase?: string; + /** @description ISO-8601. */ + startedAt?: string; + /** @description ISO-8601. */ + heartbeatAt?: string; + elapsedMs?: number; + /** @description Running on this replica. */ + live?: boolean; + /** @description SUPERSEDE or CONCURRENT. */ + concurrencyMode?: string; + }[]; + }; + /** @description An error the client hit while showing the assistant (since 1.5.0). scope and message are required; longer values are truncated, message and stacks are scrubbed of e-mail addresses, long numbers, tokens and query strings, and ids are kept only when they are the user's own. */ + AssistantClientErrorReportV1: { + /** @description Required. Where it happened: assistant-panel, assistant-message, assistant-part, assistant-render, assistant-stream, widget, record-section, page... */ + scope?: string; + /** @description Required. The error message. */ + message?: string; + /** @description The error's name, e.g. TypeError. */ + errorName?: string | null; + /** @description The JavaScript stack. */ + stack?: string | null; + /** @description The React component stack. */ + componentStack?: string | null; + /** @description The request or trace id the client saw. */ + requestId?: string | null; + /** @description The page path (no host, query or fragment). */ + route?: string | null; + conversationId?: number | null; + messageId?: number | null; + turnId?: number | null; + /** @description The message part type being shown. */ + partType?: string | null; + /** @description The render type being shown. */ + renderType?: string | null; + /** @description The client build. */ + appVersion?: string | null; + /** + * Format: date-time + * @description ISO-8601 instant. + */ + occurredAt?: string | null; + }; + /** @description Whether the report was stored: false when the user's reports are over the per-minute limit (still 202). */ + AssistantClientErrorResponseV1: { + accepted?: boolean; + }; + /** @description Whether the assistant is available to this user, and how. */ + AssistantConfigResponseV1: { + /** @description Whether the panel may be used. */ + enabled?: boolean; + /** @description Why not: DISABLED, NO_PERMISSION, NOT_CONFIGURED or KILL_SWITCH. */ + reason?: string | null; + /** @description Keyboard shortcut, e.g. mod+j. */ + shortcut?: string; + /** @description The model that answers. */ + model?: string; + /** @description maxTurnSeconds and maxToolCallsPerTurn. When features.attachments is true also maxAttachmentBytes (the largest file read, in bytes), maxAttachments (files per question) and attachmentTypes (human-readable type names for the file picker hint; images only when the model reads them). */ + limits?: { + [key: string]: unknown; + }; + /** @description writes: some table allows writes; pendingActions: writes wait for confirmation; attachments: files uploaded with POST /qqq/v1/uploads and sent as pageContext.attachments [{uploadRef, fileName}] are read for the question. */ + features?: { + [key: string]: unknown; + }; + profile?: components["schemas"]["AssistantProfileV1"]; + /** @description Since 1.6.0: the table name of the user's conversations (assistant_conversation) for the standard table UI (manage, archive, restore and delete); present only when this session may query that table. */ + conversationsTable?: string | null; + }; + /** @description A conversation and a page of its messages, oldest first. */ + AssistantConversationDetailResponseV1: { + conversation?: components["schemas"]["AssistantConversationV1"]; + messages?: components["schemas"]["AssistantMessageV1"][]; + }; + /** @description The user's conversations, newest first. */ + AssistantConversationListResponseV1: { + conversations?: components["schemas"]["AssistantConversationV1"][]; + }; + /** @description One of the user's own conversations. */ + AssistantConversationV1: { + id?: number; + title?: string | null; + /** @description ACTIVE or ARCHIVED. */ + status?: string; + pinned?: boolean; + /** @description ISO-8601 instant. */ + lastMessageAt?: string | null; + unreadCount?: number; + /** @description ISO-8601 instant. */ + createDate?: string | null; + /** @description Since 1.6.0, in GET /conversations items only: whether an answer is in progress (a RUNNING or CANCELLING turn that is not orphaned). */ + running?: boolean | null; + }; + /** @description Deprecated since 1.3.0: errors use BasicErrorResponseV1. */ + AssistantErrorV1: { + /** @description A message for the user. */ + error?: string; + /** @description BUDGET, RATE_LIMIT, NOT_CONFIGURED, KILL_SWITCH, DISABLED, NO_PERMISSION... */ + code?: string | null; + }; + /** @description A message: the user's text or the assistant's reply as parts (text, tool, record_refs, navigate, notice). */ + AssistantMessageV1: { + id?: number; + /** @description USER or ASSISTANT. */ + role?: string; + status?: string; + turnId?: number | null; + createDate?: string | null; + parts?: { + [key: string]: unknown; + }[]; + }; + /** @description How the assistant presents itself (admin-configured; text only, it never changes access). */ + AssistantProfileV1: { + /** @description The assistant's name. */ + displayName?: string; + /** @description A Material icon name. */ + icon?: string; + /** @description Shown on a new conversation. */ + greeting?: string | null; + /** @description Up to three suggested first questions in total: permitted configured questions first, then generated questions. Table, row and field access are checked on every request. */ + starterPrompts?: string[]; + }; + /** @description A tool part's render of type records (query results). columns and rows are always present - empty when the query matched nothing (since 1.4.0; older stored parts are completed when read). */ + AssistantRecordsRenderV1: { + /** @description records */ + type?: string; + tableName?: string; + tableLabel?: string; + /** @description Always present; empty when nothing matched. */ + columns?: { + name?: string; + label?: string; + }[]; + /** @description Always present; empty when nothing matched. */ + rows?: { + /** @description The primary key. */ + id?: string; + /** @description The record's /app link. */ + href?: string; + /** @description Display values by column name. */ + values?: { + [key: string]: unknown; + }; + }[]; + /** @description All matching rows. */ + totalCount?: number | null; + /** @description More rows match than are shown. */ + truncated?: boolean; + /** @description The Query screen link. */ + openHref?: string; + }; + /** @description An acknowledgement. */ + AssistantStatusResponseV1: { + status?: string; + }; + /** @description One server-sent event of a turn (event: , id: , data: this object). Types: message.start, turn.phase, text.delta, tool.start, tool.result, ui.navigate, notice, usage, message.end, error, ping. */ + AssistantTurnEventV1: { + /** @description Sequence number; resume with ?after=. */ + seq?: number; + /** @description The event type (also the SSE event name). */ + type?: string; + /** @description The event's fields, by type. message.start includes startedAt (ISO-8601). turn.phase includes phase (thinking, tool, writing), optional toolName and label. */ + data?: { + [key: string]: unknown; + }; + }; + CollaborationAccessRequestCreateRequestV1: { + /** @description message. */ + message?: string | null; + /** @description recordId. */ + recordId?: string | null; + /** @description shareId. */ + shareId?: number | null; + /** @description tableName. */ + tableName?: string | null; + }; + CollaborationAccessRequestListV1: { + /** @description items. */ + items?: components["schemas"]["CollaborationAccessRequestV1"][] | null; + /** @description nextCursor. */ + nextCursor?: string | null; + }; + CollaborationAccessRequestV1: { + /** + * Format: date-time + * @description handledAt. + */ + handledAt?: string | null; + /** @description Display name of the person who handled the request. */ + handledByDisplayName?: string | null; + /** @description id. */ + id?: number | null; + /** @description message. */ + message?: string | null; + /** @description note. */ + note?: string | null; + /** @description recordId. */ + recordId?: string | null; + /** @description Requester display name. */ + requesterDisplayName?: string | null; + /** @description requesterUserId. */ + requesterUserId?: string | null; + /** @description status. */ + status?: string | null; + /** @description tableName. */ + tableName?: string | null; + }; + CollaborationAssignmentRequestV1: { + /** @description assigneeUserId. */ + assigneeUserId?: string | null; + /** @description ownerUserId. */ + ownerUserId?: string | null; + }; + CollaborationAssignmentV1: { + /** @description Assignee display name. */ + assigneeDisplayName?: string | null; + /** @description assigneeUserId. */ + assigneeUserId?: string | null; + /** @description id. */ + id?: number | null; + /** @description Owner display name. */ + ownerDisplayName?: string | null; + /** @description ownerUserId. */ + ownerUserId?: string | null; + /** @description recordId. */ + recordId?: string | null; + /** @description tableName. */ + tableName?: string | null; + }; + /** @description Attachments, newest first. */ + CollaborationAttachmentListV1: { + /** @description Attachments, newest first. */ + items?: components["schemas"]["CollaborationAttachmentV1"][] | null; + /** @description Opaque continuation token; null when finished or the service has no continuation support. */ + nextCursor?: string | null; + }; + /** @description Change attachment display metadata. */ + CollaborationAttachmentPatchRequestV1: { + /** @description Optional description; empty clears, null leaves unchanged. */ + description?: string | null; + /** @description Optional new display filename; null leaves unchanged. */ + fileName?: string | null; + }; + /** @description Multipart upload with exactly one file part named file. */ + CollaborationAttachmentUploadRequestV1: { + /** @description Optional description. */ + description?: string | null; + /** + * Format: binary + * @description Required file content. + */ + file?: string | null; + }; + /** @description An attachment visible through its parent record; no storage coordinates are exposed. */ + CollaborationAttachmentV1: { + /** @description Whether the caller may change or delete this attachment. */ + canDelete?: boolean | null; + /** @description MIME content type. */ + contentType?: string | null; + /** + * Format: date-time + * @description Upload time. + */ + createDate?: string | null; + /** @description Uploader display name. */ + createdByDisplayName?: string | null; + /** @description Uploader identity. */ + createdByUserId?: string | null; + /** @description Optional description. */ + description?: string | null; + /** @description Safe display filename. */ + fileName?: string | null; + /** @description Attachment identifier. */ + id?: number | null; + /** @description Canonical parent record key. */ + recordId?: string | null; + /** @description SHA-256 content digest. */ + sha256?: string | null; + /** @description Stored byte count. */ + sizeBytes?: number | null; + /** @description Parent table metadata name. */ + tableName?: string | null; + }; + /** @description Replace the caller's comment body. */ + CollaborationCommentEditRequestV1: { + /** @description Required replacement body, 1 to 20000 characters. */ + body?: string | null; + }; + /** @description Previous bodies in edit order. */ + CollaborationCommentHistoryV1: { + /** @description Previous bodies in edit order. */ + items?: components["schemas"]["CollaborationCommentRevisionV1"][] | null; + /** @description Opaque continuation token; null when finished or the service has no continuation support. */ + nextCursor?: string | null; + }; + /** @description Root threads by latest activity, with replies. */ + CollaborationCommentPageV1: { + /** @description Opaque continuation token; null when finished or the service has no continuation support. */ + nextCursor?: string | null; + /** @description Root threads by latest activity, with replies. */ + threads?: components["schemas"]["CollaborationCommentV1"][] | null; + }; + /** @description Post a root comment or one-level reply. */ + CollaborationCommentPostRequestV1: { + /** @description Required body, 1 to 20000 characters; mentions use @[Name](user:id). */ + body?: string | null; + /** @description Optional existing parent field name. */ + fieldName?: string | null; + /** @description Optional comment to reply to. */ + parentCommentId?: number | null; + }; + /** @description A previous comment body. */ + CollaborationCommentRevisionV1: { + /** @description Previous body text. */ + body?: string | null; + /** + * Format: date-time + * @description Time the body was replaced. + */ + editedAt?: string | null; + /** @description Editor display name. */ + editedByDisplayName?: string | null; + /** @description Editor identity. */ + editedByUserId?: string | null; + /** @description Revision identifier. */ + id?: number | null; + }; + /** @description A comment or reply; deleted comments retain their position without body text. */ + CollaborationCommentV1: { + /** @description Author display name. */ + authorDisplayName?: string | null; + /** @description Author identity. */ + authorUserId?: string | null; + /** @description Plain text with mention tokens; null for deleted comments. */ + body?: string | null; + /** @description Caller may delete this comment. */ + canDelete?: boolean | null; + /** @description Caller may edit the body. */ + canEdit?: boolean | null; + /** + * Format: date-time + * @description Creation time. + */ + createdAt?: string | null; + /** @description Whether the comment is soft deleted. */ + deleted?: boolean | null; + /** + * Format: date-time + * @description Last edit time, if edited. + */ + editedAt?: string | null; + /** @description Optional field being discussed. */ + fieldName?: string | null; + /** @description Comment identifier. */ + id?: number | null; + /** @description Mention recipients. */ + mentions?: components["schemas"]["CollaborationMentionV1"][] | null; + /** @description Root comment for a reply; null on roots. */ + parentCommentId?: number | null; + /** @description Replies in oldest-first order; empty on replies. */ + replies?: components["schemas"]["CollaborationCommentV1"][] | null; + /** @description Whether the thread is resolved. */ + resolved?: boolean | null; + /** @description Root thread identifier; null on roots. */ + threadId?: number | null; + }; + /** @description Temporary access to file bytes. Clients follow url. */ + CollaborationDownloadV1: { + /** @description Presigned URL, valid for five minutes. Clients follow url; never persist it. */ + url?: string | null; + }; + /** @description Deprecated since 1.1.0: errors use BasicErrorResponseV1. */ + CollaborationErrorV1: { + /** @description Human-readable reason the operation failed. */ + error?: string | null; + }; + /** @description Ordered personal favorites. */ + CollaborationFavoriteListV1: { + /** @description Ordered personal favorites. */ + items?: components["schemas"]["CollaborationFavoriteV1"][] | null; + /** @description Opaque continuation token; null when finished or the service has no continuation support. */ + nextCursor?: string | null; + }; + /** @description Move selected favorites first and optionally assign folders. */ + CollaborationFavoriteOrderRequestV1: { + /** @description Optional map from favorite identifier to folder; null values clear folders. */ + folders?: { + [key: string]: string | null; + } | null; + /** @description Required ordered favorite identifiers, with no duplicates. */ + ids?: number[] | null; + }; + /** @description A saved navigation target, with availability rechecked for the caller. */ + CollaborationFavoriteV1: { + /** @description Whether the caller can currently open this target. */ + available?: boolean | null; + /** @description Optional personal grouping. */ + folder?: string | null; + /** @description Navigation link, absent for unavailable targets. */ + href?: string | null; + /** @description Favorite identifier. */ + id?: number | null; + /** @description Current display label; Unavailable when access is lost. */ + label?: string | null; + /** @description Canonical record key; null for non-record targets. */ + recordId?: string | null; + /** @description Position in the personal list. */ + sortOrder?: number | null; + /** @description Metadata name of the table, app, process, report or saved view. */ + targetName?: string | null; + /** + * @description Kind of navigation target. + * @enum {string|null} + */ + targetType?: "TABLE" | "APP" | "RECORD" | "PROCESS" | "REPORT" | "SAVED_VIEW" | null; + }; + /** @description Configure the caller's follow preferences. */ + CollaborationFollowRequestV1: { + /** @description Optional change notifications preference; omission retains current setting. */ + notifyOnChange?: boolean | null; + /** @description Optional comment notifications preference; omission retains current setting. */ + notifyOnComment?: boolean | null; + }; + /** @description The current caller's subscription state. */ + CollaborationFollowStateV1: { + /** @description Subscription settings; null when not following. */ + follow?: components["schemas"]["CollaborationFollowV1"]; + /** @description Whether the caller follows the record. */ + following?: boolean | null; + }; + /** @description A subscription to record changes and comments. */ + CollaborationFollowV1: { + /** @description Subscription identifier. */ + id?: number | null; + /** + * Format: date-time + * @description Notifications muted until this time, if set. + */ + mutedUntil?: string | null; + /** @description Receive record change digests. */ + notifyOnChange?: boolean | null; + /** @description Receive new comment notifications. */ + notifyOnComment?: boolean | null; + /** + * @description How following began. + * @enum {string|null} + */ + reason?: "MANUAL" | "AUTHOR" | "COMMENTED" | "MENTIONED" | "ASSIGNED" | "SHARED" | null; + /** @description Follower display name. */ + userDisplayName?: string | null; + /** @description Follower identity. */ + userId?: string | null; + }; + /** @description Subscriptions for this record. */ + CollaborationFollowerListV1: { + /** @description Subscriptions for this record. */ + items?: components["schemas"]["CollaborationFollowV1"][] | null; + /** @description Opaque continuation token; null when finished or the service has no continuation support. */ + nextCursor?: string | null; + }; + CollaborationLinkV1: { + /** @description label. */ + label?: string | null; + /** @description url. */ + url?: string | null; + }; + /** @description Candidates ranked with record participants first. */ + CollaborationMentionCandidateListV1: { + /** @description Candidates ranked with record participants first. */ + items?: components["schemas"]["CollaborationMentionCandidateV1"][] | null; + /** @description Opaque continuation token; null when finished or the service has no continuation support. */ + nextCursor?: string | null; + }; + /** @description A matching person and their known parent access. */ + CollaborationMentionCandidateV1: { + /** + * @description Recipient access: string true, false, or unknown when it cannot be established. + * @enum {string|null} + */ + canRead?: "true" | "false" | "unknown" | null; + /** @description Directory identity. */ + person?: components["schemas"]["CollaborationPersonV1"]; + }; + /** @description A mention embedded in a comment. */ + CollaborationMentionV1: { + /** @description Mentioned user identity. */ + userId?: string | null; + /** @description Whether recipient access was confirmed when mentioned. */ + visible?: boolean | null; + }; + /** @description Acknowledgement of a completed mutation. */ + CollaborationMutationResultV1: { + /** @description True after the requested operation completes. */ + success?: boolean | null; + }; + CollaborationMyWorkV1: { + /** @description assignedRecordsByTable. */ + assignedRecordsByTable?: { + [key: string]: number; + } | null; + /** @description openTaskCount. */ + openTaskCount?: number | null; + /** @description tasks. */ + tasks?: components["schemas"]["CollaborationTaskV1"][] | null; + /** @description unreadMentionCount. */ + unreadMentionCount?: number | null; + }; + /** @description Matching active directory entries. */ + CollaborationPersonListV1: { + /** @description Matching active directory entries. */ + items?: components["schemas"]["CollaborationPersonV1"][] | null; + /** @description Opaque continuation token; null when finished or the service has no continuation support. */ + nextCursor?: string | null; + }; + /** @description An active directory entry. */ + CollaborationPersonV1: { + /** @description Display name. */ + displayName?: string | null; + /** @description Directory email, if known. */ + email?: string | null; + /** + * Format: date-time + * @description Most recent directory refresh time. + */ + lastSeenAt?: string | null; + /** @description Stable user identity. */ + userId?: string | null; + }; + /** @description Remove the caller's lease on this connection and target. */ + CollaborationPresenceLeaveV1: { + /** @description Client connection identity. */ + connectionId?: string; + /** @description Optional parent key. */ + pk?: string | null; + /** @description Parent table name. */ + table?: string; + }; + /** @description Renew a 45-second presence lease; send every 20 seconds. */ + CollaborationPresenceRequestV1: { + /** @description Client connection identity. */ + connectionId?: string; + /** @description Optional focused field on a record. */ + fieldName?: string | null; + /** + * @description VIEWING or EDITING. + * @enum {string} + */ + mode?: "VIEWING" | "EDITING"; + /** @description Optional parent key; omit for a table view. */ + pk?: string | null; + /** @description Parent table name. */ + table?: string; + }; + /** @description Live viewers, merged across tabs; presence.changed uses this payload. */ + CollaborationPresenceSnapshotV1: { + /** @description Record key; absent for table events. */ + pk?: string | null; + /** @description Parent table name. */ + table?: string; + viewers?: components["schemas"]["CollaborationPresenceViewerV1"][]; + }; + /** @description One user merged across live tabs; EDITING takes precedence. */ + CollaborationPresenceViewerV1: { + /** @description Session display name. */ + displayName?: string; + /** @description Focused field; null on table snapshots. */ + fieldName?: string | null; + /** + * @description VIEWING or EDITING. + * @enum {string} + */ + mode?: "VIEWING" | "EDITING"; + /** @description Stable user identity. */ + userId?: string; + }; + /** @description Most recent visible targets, at most fifty. */ + CollaborationRecentListV1: { + /** @description Most recent visible targets, at most fifty. */ + items?: components["schemas"]["CollaborationFavoriteV1"][] | null; + /** @description Opaque continuation token; null when finished or the service has no continuation support. */ + nextCursor?: string | null; + }; + CollaborationShareListV1: { + /** @description items. */ + items?: components["schemas"]["CollaborationShareV1"][] | null; + }; + CollaborationSharePreviewV1: { + /** @description recipients. */ + recipients?: components["schemas"]["CollaborationShareRecipientV1"][] | null; + }; + CollaborationShareRecipientV1: { + /** @description canRead. */ + canRead?: boolean | null; + /** @description displayName. */ + displayName?: string | null; + /** @description userId. */ + userId?: string | null; + }; + CollaborationShareRequestV1: { + /** @description message. */ + message?: string | null; + /** @description toUserIds. */ + toUserIds?: string[] | null; + }; + CollaborationShareV1: { + /** @description Sender display name. */ + fromDisplayName?: string | null; + /** @description fromUserId. */ + fromUserId?: string | null; + /** @description id. */ + id?: number | null; + /** @description message. */ + message?: string | null; + /** @description recipientCouldRead. */ + recipientCouldRead?: boolean | null; + /** @description recordId. */ + recordId?: string | null; + /** + * Format: date-time + * @description sentAt. + */ + sentAt?: string | null; + /** @description tableName. */ + tableName?: string | null; + /** @description Recipient display name. */ + toDisplayName?: string | null; + /** @description toUserId. */ + toUserId?: string | null; + }; + /** @description Add and remove tag associations in one request. */ + CollaborationTagApplyRequestV1: { + /** @description Tag identifiers to add; omitted means none. */ + add?: number[] | null; + /** @description Tag identifiers to remove; omitted means none. */ + remove?: number[] | null; + }; + /** @description Create a tag or suggest one under the table policy. */ + CollaborationTagCreateRequestV1: { + /** @description Optional display color. */ + color?: string | null; + /** @description Required display label, 1 to 60 characters. */ + label?: string | null; + /** @description Required table metadata name. */ + table?: string | null; + }; + /** @description Available or applied tags. */ + CollaborationTagListV1: { + /** @description Available or applied tags. */ + items?: components["schemas"]["CollaborationTagV1"][] | null; + /** @description Opaque continuation token; null when finished or the service has no continuation support. */ + nextCursor?: string | null; + }; + /** @description An approved tag or the caller's pending suggestion. */ + CollaborationTagV1: { + /** @description Whether anyone may apply this tag. */ + approved?: boolean | null; + /** @description Optional display color. */ + color?: string | null; + /** @description Tag identifier. */ + id?: number | null; + /** @description Display label. */ + label?: string | null; + /** @description Normalized vocabulary name. */ + name?: string | null; + /** @description Table scope; null means global. */ + tableName?: string | null; + /** @description Number of record associations. */ + usageCount?: number | null; + }; + /** @description Target to star, unstar, or record as recently viewed. */ + CollaborationTargetRequestV1: { + /** @description Required for RECORD; omitted otherwise. */ + recordId?: string | null; + /** @description Required metadata name. */ + targetName?: string | null; + /** + * @description Required target kind. + * @enum {string|null} + */ + targetType?: "TABLE" | "APP" | "RECORD" | "PROCESS" | "REPORT" | "SAVED_VIEW" | null; + }; + CollaborationTaskCreateRequestV1: { + /** @description assigneeUserId. */ + assigneeUserId?: string | null; + /** + * Format: date-time + * @description dueAt. + */ + dueAt?: string | null; + /** @description notes. */ + notes?: string | null; + /** + * Format: date-time + * @description remindAt. + */ + remindAt?: string | null; + /** @description title. */ + title?: string | null; + }; + CollaborationTaskListV1: { + /** @description items. */ + items?: components["schemas"]["CollaborationTaskV1"][] | null; + /** @description nextCursor. */ + nextCursor?: string | null; + }; + CollaborationTaskPatchRequestV1: { + /** @description assigneeUserId. */ + assigneeUserId?: string | null; + /** + * Format: date-time + * @description dueAt. + */ + dueAt?: string | null; + /** @description notes. */ + notes?: string | null; + /** + * Format: date-time + * @description remindAt. + */ + remindAt?: string | null; + /** @description status. */ + status?: string | null; + /** @description title. */ + title?: string | null; + }; + CollaborationTaskV1: { + /** @description Assignee display name. */ + assigneeDisplayName?: string | null; + /** @description assigneeUserId. */ + assigneeUserId?: string | null; + /** + * Format: date-time + * @description completedAt. + */ + completedAt?: string | null; + /** @description Display name of the person who completed the task. */ + completedByDisplayName?: string | null; + /** @description completedByUserId. */ + completedByUserId?: string | null; + /** @description Creator display name. */ + createdByDisplayName?: string | null; + /** @description createdByUserId. */ + createdByUserId?: string | null; + /** + * Format: date-time + * @description dueAt. + */ + dueAt?: string | null; + /** @description id. */ + id?: number | null; + /** @description notes. */ + notes?: string | null; + /** @description recordId. */ + recordId?: string | null; + /** + * Format: date-time + * @description remindAt. + */ + remindAt?: string | null; + /** @description status. */ + status?: string | null; + /** @description tableName. */ + tableName?: string | null; + /** @description title. */ + title?: string | null; + }; + /** @description A permitted field change from a core audit. */ + CollaborationTimelineDetailV1: { + /** @description Changed field metadata name. */ + fieldName?: string | null; + /** @description Optional audit message. */ + message?: string | null; + /** @description New display value. */ + newValue?: string | null; + /** @description Previous display value. */ + oldValue?: string | null; + }; + /** @description One visible event in the merged record timeline. */ + CollaborationTimelineItemV1: { + /** @description Actor display name. */ + actorName?: string | null; + /** @description Actor identity, when known. */ + actorUserId?: string | null; + /** + * Format: date-time + * @description Event time. + */ + at?: string | null; + /** @description Field details filtered by caller permissions. */ + details?: components["schemas"]["CollaborationTimelineDetailV1"][] | null; + /** @description Identifier within the source. */ + id?: number | null; + /** + * @description Event source. + * @enum {string|null} + */ + kind?: "ACTIVITY" | "AUDIT" | null; + /** @description Related record key. */ + refId?: string | null; + /** @description Related table metadata name. */ + refTable?: string | null; + /** @description Human-readable event summary. */ + summary?: string | null; + }; + /** @description Merged events, newest first. */ + CollaborationTimelinePageV1: { + /** @description Merged events, newest first. */ + items?: components["schemas"]["CollaborationTimelineItemV1"][] | null; + /** @description Opaque continuation token; null when finished or the service has no continuation support. */ + nextCursor?: string | null; + }; + DataAnalysisAxisV1: { + /** @description Field. */ + field?: string | null; + /** @description Label. */ + label?: string | null; + /** + * @description Value type. + * @enum {string|null} + */ + valueType?: "COUNT" | "DECIMAL" | "PERCENT" | "DATE" | "DATE_TIME" | "DURATION" | "TEXT" | null; + } | null; + DataAnalysisCandidateKeyV1: { + /** @description Readable fields to include; omit for all analyzable fields on a table profile. */ + fields?: string[] | null; + /** @description Row count. */ + rowCount?: number | null; + /** @description Open the matching records using this table and QueryFilter; null when suppressed. */ + drill?: components["schemas"]["DataAnalysisDrillV1"]; + } | null; + DataAnalysisCapabilitiesV1: { + /** @description Whether this session may analyze the table; false responses expose no fields. */ + canAnalyze?: boolean | null; + /** @description Table name. */ + tableName?: string | null; + /** @description Table label. */ + tableLabel?: string | null; + /** @description Readable fields to include; omit for all analyzable fields on a table profile. */ + fields?: components["schemas"]["DataAnalysisCapabilityFieldV1"][] | null; + /** @description Limits. */ + limits?: components["schemas"]["DataAnalysisLimitsV1"]; + /** @description Backend capabilities. */ + backendCapabilities?: string[] | null; + /** @description Whether SQL Workbench metadata is installed in this instance. */ + sqlWorkbenchAvailable?: boolean | null; + } | null; + DataAnalysisCapabilityFieldV1: { + /** @description Name. */ + name?: string | null; + /** @description Label. */ + label?: string | null; + /** @description Type. */ + type?: string | null; + /** @description Semantic field kind: NUMERIC, DATE, DATE_TIME, TEXT, BOOLEAN or CATEGORY. */ + kind?: string | null; + /** + * @description Default chart kind. + * @enum {string|null} + */ + defaultChartKind?: "HISTOGRAM" | "BOX" | "BAR" | "PARETO" | "TIME_SERIES" | "SCATTER" | "HEATMAP" | null; + } | null; + DataAnalysisChartV1: { + /** @description Stack category series to a total share of one when true. */ + stacked?: boolean | null; + /** + * @description Semantic field kind: NUMERIC, DATE, DATE_TIME, TEXT, BOOLEAN or CATEGORY. + * @enum {string|null} + */ + kind?: "HISTOGRAM" | "BOX" | "BAR" | "PARETO" | "TIME_SERIES" | "SCATTER" | "HEATMAP" | null; + /** @description Alternatives. */ + alternatives?: ("HISTOGRAM" | "BOX" | "BAR" | "PARETO" | "TIME_SERIES" | "SCATTER" | "HEATMAP")[] | null; + /** @description X. */ + x?: components["schemas"]["DataAnalysisAxisV1"]; + /** @description Y. */ + y?: components["schemas"]["DataAnalysisAxisV1"]; + /** @description Series. */ + series?: components["schemas"]["DataAnalysisSeriesV1"][] | null; + /** @description Annotations. */ + annotations?: string[] | null; + } | null; + DataAnalysisColumnProfileRequestV1: { + /** @description Core QueryFilter JSON, identical to the table query and count endpoints. */ + filter?: components["schemas"]["QueryFilter"]; + /** @description Request exact computation instead of the configured estimate. */ + exact?: boolean; + /** @description Readable field name to profile or enumerate. */ + fieldName: string; + }; + DataAnalysisColumnProfileV1: { + /** @description Table name. */ + tableName?: string | null; + /** @description Core QueryFilter JSON, identical to the table query and count endpoints. */ + filter?: components["schemas"]["QueryFilter"]; + /** @description True when statistics describe a sample rather than the entire filtered population. */ + estimate?: boolean | null; + /** @description Actual number of rows in the sample, not an extrapolated count. */ + sampleRows?: number | null; + /** @description True when the row limit prevented a complete scan. */ + truncated?: boolean | null; + /** @description Number of source rows included in computation. */ + rowsScanned?: number | null; + /** + * Format: date-time + * @description As of. + */ + asOf?: string | null; + /** @description Data version. */ + dataVersion?: string | null; + /** @description Warnings. */ + warnings?: string[] | null; + /** @description Readable field name to profile or enumerate. */ + fieldName?: string | null; + /** @description Field label. */ + fieldLabel?: string | null; + /** @description Field type. */ + fieldType?: string | null; + /** @description Counts. */ + counts?: components["schemas"]["DataAnalysisMetricV1"][] | null; + /** @description Numeric. */ + numeric?: components["schemas"]["DataAnalysisNumericProfileV1"]; + /** @description Dates. */ + dates?: components["schemas"]["DataAnalysisDateProfileV1"]; + /** @description Text. */ + text?: components["schemas"]["DataAnalysisTextProfileV1"]; + /** @description Booleans. */ + booleans?: components["schemas"]["DataAnalysisMetricV1"][] | null; + /** @description Top values. */ + topValues?: components["schemas"]["DataAnalysisValueCountV1"][] | null; + /** @description Chart. */ + chart?: components["schemas"]["DataAnalysisChartV1"]; + } | null; + DataAnalysisCompareRequestV1: { + /** @description Population A filter; null selects the whole permitted table. */ + filterA?: components["schemas"]["QueryFilter"]; + /** @description Population B filter; null selects the whole permitted table. */ + filterB?: components["schemas"]["QueryFilter"]; + /** @description Display name of population A; default A. */ + labelA?: string; + /** @description Display name of population B; default B. */ + labelB?: string; + /** @description Distinct FULL fields to analyze; correlation requires 2 to 12 numeric fields. */ + fields: string[]; + }; + DataAnalysisCompareV1: { + /** @description Distinct FULL fields to analyze; correlation requires 2 to 12 numeric fields. */ + fields?: components["schemas"]["DataAnalysisFieldComparisonV1"][] | null; + }; + DataAnalysisComparisonSideV1: { + /** @description Label. */ + label?: string | null; + /** @description Typed metrics with exact population drills unless privacy suppresses them. */ + metrics?: components["schemas"]["DataAnalysisMetricV1"][] | null; + }; + DataAnalysisComparisonValueV1: { + /** @description Value. */ + value?: unknown; + /** @description Label. */ + label?: string | null; + /** @description Side a. */ + sideA?: components["schemas"]["DataAnalysisComparisonSideV1"]; + /** @description Side b. */ + sideB?: components["schemas"]["DataAnalysisComparisonSideV1"]; + /** @description B minus A, in original units (share differences are fractions). */ + delta?: components["schemas"]["DataAnalysisMetricV1"]; + /** @description (B minus A) divided by absolute A, a fraction; null at a zero baseline. */ + percentDelta?: components["schemas"]["DataAnalysisMetricV1"]; + /** @description Test assumptions, two-sided p-value, degrees of freedom and plain-language conclusion. */ + significance?: components["schemas"]["DataAnalysisSignificanceV1"]; + }; + DataAnalysisCorrelationCellV1: { + /** @description FULL numeric field on the x axis. */ + xField?: string | null; + /** @description FULL numeric field on the y axis. */ + yField?: string | null; + /** @description Pairwise non-null population count; null when privacy suppresses it. */ + n?: number | null; + /** @description Pearson correlation; null for insufficient data, zero variance or privacy suppression. */ + r?: number | null; + /** @description POST the included parameters to the table scatter endpoint. */ + scatter?: components["schemas"]["DataAnalysisScatterRequestV1"]; + }; + DataAnalysisCorrelationRequestV1: { + /** @description Current-user query filter; record locks and core field rules apply. */ + filter?: components["schemas"]["QueryFilter"]; + /** @description Distinct FULL fields to analyze; correlation requires 2 to 12 numeric fields. */ + fields: string[]; + }; + DataAnalysisCorrelationV1: { + /** @description Distinct FULL fields to analyze; correlation requires 2 to 12 numeric fields. */ + fields?: string[] | null; + /** @description Cells. */ + cells?: components["schemas"]["DataAnalysisCorrelationCellV1"][] | null; + /** @description Semantic series; category comparisons are grouped and category time series are stacked. */ + chart?: components["schemas"]["DataAnalysisChartV1"]; + }; + DataAnalysisCrosstabCellV1: { + /** @description Row index. */ + rowIndex?: number | null; + /** @description Column index. */ + columnIndex?: number | null; + /** @description Cell count with its exact drill, or a suppressed metric. */ + count?: components["schemas"]["DataAnalysisMetricV1"]; + /** @description Cell count divided by row total; suppressed if it could disclose a hidden cell. */ + rowShare?: components["schemas"]["DataAnalysisMetricV1"]; + /** @description Cell count divided by column total; suppressed if it could disclose a hidden cell. */ + columnShare?: components["schemas"]["DataAnalysisMetricV1"]; + }; + DataAnalysisCrosstabRequestV1: { + /** @description Current-user query filter; record locks and core field rules apply. */ + filter?: components["schemas"]["QueryFilter"]; + /** @description FULL field defining crosstab rows. */ + rowField: string; + /** @description FULL field defining crosstab columns. */ + columnField: string; + /** @description Maximum sample points (1 to 2000, default 2000) or kept crosstab categories per axis (1 to 20, default 20). */ + limit?: number; + }; + DataAnalysisCrosstabV1: { + /** @description Rows. */ + rows?: components["schemas"]["DataAnalysisPivotHeaderV1"][] | null; + /** @description Columns. */ + columns?: components["schemas"]["DataAnalysisPivotHeaderV1"][] | null; + /** @description Cells. */ + cells?: components["schemas"]["DataAnalysisCrosstabCellV1"][] | null; + /** @description Test assumptions, two-sided p-value, degrees of freedom and plain-language conclusion. */ + significance?: components["schemas"]["DataAnalysisSignificanceV1"]; + }; + DataAnalysisDateProfileV1: { + /** @description Metrics. */ + metrics?: components["schemas"]["DataAnalysisMetricV1"][] | null; + /** @description Unit. */ + unit?: string | null; + /** @description Buckets. */ + buckets?: components["schemas"]["DataAnalysisValueCountV1"][] | null; + /** @description Gaps. */ + gaps?: components["schemas"]["DataAnalysisValueCountV1"][] | null; + /** @description Day of week. */ + dayOfWeek?: components["schemas"]["DataAnalysisValueCountV1"][] | null; + /** @description Hour of day. */ + hourOfDay?: components["schemas"]["DataAnalysisValueCountV1"][] | null; + } | null; + DataAnalysisDistinctValuesPageV1: { + /** @description Table name. */ + tableName?: string | null; + /** @description Core QueryFilter JSON, identical to the table query and count endpoints. */ + filter?: components["schemas"]["QueryFilter"]; + /** @description True when statistics describe a sample rather than the entire filtered population. */ + estimate?: boolean | null; + /** @description Actual number of rows in the sample, not an extrapolated count. */ + sampleRows?: number | null; + /** @description True when the row limit prevented a complete scan. */ + truncated?: boolean | null; + /** @description Number of source rows included in computation. */ + rowsScanned?: number | null; + /** + * Format: date-time + * @description As of. + */ + asOf?: string | null; + /** @description Data version. */ + dataVersion?: string | null; + /** @description Warnings. */ + warnings?: string[] | null; + /** @description Readable field name to profile or enumerate. */ + fieldName?: string | null; + /** @description Zero-based page number. */ + page?: number | null; + /** @description Maximum values per page, from 1 to 500. */ + pageSize?: number | null; + /** @description Has more. */ + hasMore?: boolean | null; + /** @description Total distinct. */ + totalDistinct?: number | null; + /** @description Values. */ + values?: components["schemas"]["DataAnalysisValueCountV1"][] | null; + } | null; + DataAnalysisDistinctValuesRequestV1: { + /** @description Core QueryFilter JSON, identical to the table query and count endpoints. */ + filter?: components["schemas"]["QueryFilter"]; + /** @description Readable field name to profile or enumerate. */ + fieldName: string; + /** @description Zero-based page number. */ + page?: number; + /** @description Maximum values per page, from 1 to 500. */ + pageSize?: number; + /** @description Optional search text applied to stored values. */ + search?: string; + }; + DataAnalysisDrillV1: { + /** @description Table name. */ + tableName?: string | null; + /** @description Core QueryFilter JSON, identical to the table query and count endpoints. */ + filter?: components["schemas"]["QueryFilter"]; + } | null; + DataAnalysisDuplicatesRequestV1: { + /** @description Core QueryFilter JSON, identical to the table query and count endpoints. */ + filter?: components["schemas"]["QueryFilter"]; + /** @description Readable fields to include; omit for all analyzable fields on a table profile. */ + fields: string[]; + /** @description Maximum duplicate groups to return, from 1 to 500; default 50. */ + limit?: number; + }; + DataAnalysisDuplicatesResultV1: { + /** @description Table name. */ + tableName?: string | null; + /** @description Core QueryFilter JSON, identical to the table query and count endpoints. */ + filter?: components["schemas"]["QueryFilter"]; + /** @description True when statistics describe a sample rather than the entire filtered population. */ + estimate?: boolean | null; + /** @description Actual number of rows in the sample, not an extrapolated count. */ + sampleRows?: number | null; + /** @description True when the row limit prevented a complete scan. */ + truncated?: boolean | null; + /** @description Number of source rows included in computation. */ + rowsScanned?: number | null; + /** + * Format: date-time + * @description As of. + */ + asOf?: string | null; + /** @description Data version. */ + dataVersion?: string | null; + /** @description Warnings. */ + warnings?: string[] | null; + /** @description Readable fields to include; omit for all analyzable fields on a table profile. */ + fields?: string[] | null; + /** @description Groups. */ + groups?: components["schemas"]["DataAnalysisValueCountV1"][] | null; + } | null; + DataAnalysisFieldComparisonV1: { + /** @description FULL field whose distribution is compared over time. */ + field?: string | null; + /** @description Values. */ + values?: components["schemas"]["DataAnalysisComparisonValueV1"][] | null; + /** @description Test assumptions, two-sided p-value, degrees of freedom and plain-language conclusion. */ + significance?: components["schemas"]["DataAnalysisSignificanceV1"]; + /** @description Semantic series; category comparisons are grouped and category time series are stacked. */ + chart?: components["schemas"]["DataAnalysisChartV1"]; + }; + DataAnalysisFieldSummaryV1: { + /** @description Field. */ + field?: string | null; + /** @description Label. */ + label?: string | null; + /** @description Type. */ + type?: string | null; + /** @description Non-empty share as a 0..1 ratio rounded to six decimals. */ + completeness?: number | null; + /** @description Distinct. */ + distinct?: number | null; + /** @description Distinct share as a 0..1 ratio rounded to six decimals. */ + uniqueness?: number | null; + /** @description Constant. */ + constant?: boolean | null; + /** @description Empty. */ + empty?: boolean | null; + /** @description Nulls. */ + nulls?: components["schemas"]["DataAnalysisMetricV1"]; + /** @description Blanks. */ + blanks?: components["schemas"]["DataAnalysisMetricV1"]; + } | null; + /** Format: binary */ + DataAnalysisFileV1: string; + DataAnalysisLimitsV1: { + /** @description Max rows. */ + maxRows?: number | null; + /** @description Sample threshold rows. */ + sampleThresholdRows?: number | null; + /** @description Actual number of rows in the sample, not an extrapolated count. */ + sampleRows?: number | null; + /** @description Min group size. */ + minGroupSize?: number | null; + } | null; + DataAnalysisMetricV1: { + /** @description Key. */ + key?: string | null; + /** @description Plain-English metric label, ready to display. */ + label?: string | null; + /** @description Raw numeric or temporal value. PERCENT is a 0..1 ratio rounded to six decimals; DECIMAL field statistics have ten significant digits. DATE_TIME is an ISO instant. */ + value?: (string | number | boolean | (Record | null)) | null; + /** + * @description Value type. + * @enum {string|null} + */ + valueType?: "COUNT" | "DECIMAL" | "PERCENT" | "DATE" | "DATE_TIME" | "DURATION" | "TEXT" | null; + /** @description Whether this metric is estimated; the population rows metric remains exact. */ + estimate?: boolean; + /** @description Display-ready value, including grouping, field display formats, percent signs and session-zone dates; null when absent or suppressed. */ + formatted?: string | null; + /** @description Open the matching records using this table and QueryFilter; null when suppressed. */ + drill?: components["schemas"]["DataAnalysisDrillV1"]; + /** @description Suppressed. */ + suppressed?: boolean | null; + /** @description Suppressed reason. */ + suppressedReason?: string | null; + } | null; + DataAnalysisNumericProfileV1: { + /** @description Metrics. */ + metrics?: components["schemas"]["DataAnalysisMetricV1"][] | null; + /** @description Histogram. */ + histogram?: components["schemas"]["DataAnalysisValueCountV1"][] | null; + /** @description Outliers. */ + outliers?: components["schemas"]["DataAnalysisValueCountV1"][] | null; + } | null; + DataAnalysisPivotCellV1: { + /** @description Zero-based index in rowHeaders. */ + rowIndex?: number; + /** @description Zero-based index in columnHeaders. */ + columnIndex?: number; + /** @description Metrics in requested measure order; suppressed metrics have no value or drill. */ + values?: components["schemas"]["DataAnalysisMetricV1"][]; + }; + DataAnalysisPivotDimensionV1: { + /** @description FULL field name, optionally joinTable.field through an exposed join. */ + field: string; + /** + * @description Optional calendar or cyclic bucket in the session timezone. + * @enum {string} + */ + dateBucket?: "YEAR" | "QUARTER" | "MONTH" | "WEEK" | "DAY" | "HOUR" | "DAY_OF_WEEK" | "HOUR_OF_DAY"; + /** @description Optional equal-width numeric bins; mutually exclusive with dateBucket. */ + numericBins?: components["schemas"]["DataAnalysisPivotNumericBinsV1"]; + }; + DataAnalysisPivotHeaderV1: { + /** @description Typed group key; null for a blank group or Other. */ + value?: unknown; + /** @description Display label, including Other (k groups). */ + label?: string; + }; + DataAnalysisPivotMeasureInfoV1: { + /** @description Stable measure key by request position. */ + key?: string; + /** @description Display label. */ + label?: string; + /** + * @description Semantic metric type. + * @enum {string} + */ + valueType?: "COUNT" | "DECIMAL" | "PERCENT" | "DATE" | "DATE_TIME" | "DURATION" | "TEXT"; + }; + DataAnalysisPivotMeasureV1: { + /** + * @description Aggregate operator. COUNT counts records, including null values. + * @enum {string} + */ + operator: "COUNT" | "SUM" | "AVG" | "MIN" | "MAX" | "COUNT_DISTINCT" | "PERCENTILE"; + /** @description FULL field to aggregate; optional for COUNT. */ + field?: string; + /** @description PERCENTILE only: percentile_cont fraction from 0 to 1. */ + percentile?: number; + }; + DataAnalysisPivotNumericBinsV1: { + /** @description Number of bins, 1–200; defaults to 20. */ + count?: number; + /** @description Optional explicit lower bound; otherwise a nice enclosing edge. */ + min?: number; + /** @description Optional explicit upper bound; final interior bin includes this value. */ + max?: number; + }; + DataAnalysisPivotRequestV1: { + /** @description User query filter, passed through for core enforcement. */ + filter?: components["schemas"]["QueryFilter"]; + /** @description One to three row dimensions. */ + rows: components["schemas"]["DataAnalysisPivotDimensionV1"][]; + /** @description Zero to two column dimensions; defaults to empty. */ + columns?: components["schemas"]["DataAnalysisPivotDimensionV1"][]; + /** @description One to six measures. */ + values: components["schemas"]["DataAnalysisPivotMeasureV1"][]; + /** @description Include row, column and grand totals; defaults to true. */ + showTotals?: boolean; + /** @description Kept groups per dimension; default 50, maximum 200. */ + limitGroups?: number; + }; + DataAnalysisPivotV1: { + /** @description Row header tuples in cell-index order. */ + rowHeaders?: components["schemas"]["DataAnalysisPivotHeaderV1"][][]; + /** @description Column header tuples; an empty tuple represents no column dimensions. */ + columnHeaders?: components["schemas"]["DataAnalysisPivotHeaderV1"][][]; + /** @description Measure metadata in request order. */ + measures?: components["schemas"]["DataAnalysisPivotMeasureInfoV1"][]; + /** @description Sparse cells; absent combinations are not materialized. */ + cells?: components["schemas"]["DataAnalysisPivotCellV1"][]; + /** @description Metric tuples aligned with rowHeaders; empty when totals disabled. */ + rowTotals?: components["schemas"]["DataAnalysisMetricV1"][][]; + /** @description Metric tuples aligned with columnHeaders; empty when totals disabled. */ + columnTotals?: components["schemas"]["DataAnalysisMetricV1"][][]; + /** @description Grand-total metrics; empty when totals disabled. */ + grandTotals?: components["schemas"]["DataAnalysisMetricV1"][]; + /** @description Row groups were merged into Other. */ + truncatedRows?: boolean; + /** @description Column groups were merged into Other. */ + truncatedColumns?: boolean; + /** @description True when bounded streamed fallback produced a partial result. */ + estimate?: boolean; + /** @description Privacy, partial-result and joined-drill limitations. */ + warnings?: string[]; + /** @description UTC timestamp of computation. */ + asOf?: string; + }; + DataAnalysisPointV1: { + /** @description X. */ + x?: (string | number | boolean | (Record | null)) | null; + /** @description Y. */ + y?: number | null; + /** @description Label. */ + label?: string | null; + /** @description Open the matching records using this table and QueryFilter; null when suppressed. */ + drill?: components["schemas"]["DataAnalysisDrillV1"]; + } | null; + DataAnalysisRunStartedV1: { + /** @description Run id. */ + runId?: string | null; + /** @description Status. */ + status?: string | null; + } | null; + DataAnalysisRunStatusV1: { + /** @description Run id. */ + runId?: string | null; + /** @description Status. */ + status?: string | null; + /** @description Error. */ + error?: string | null; + /** @description Completed column result; null for other operations or unfinished runs. */ + columnProfile?: components["schemas"]["DataAnalysisColumnProfileV1"]; + /** @description Completed table result; null for other operations or unfinished runs. */ + tableProfile?: components["schemas"]["DataAnalysisTableProfileV1"]; + /** + * Format: date-time + * @description Started at. + */ + startedAt?: string | null; + /** + * Format: date-time + * @description Finished at. + */ + finishedAt?: string | null; + } | null; + DataAnalysisSavedEntryV1: { + id?: number; + name?: string; + kind?: string; + tableName?: string; + tableLabel?: string; + owner?: string; + /** Format: date-time */ + updated?: string | null; + shared?: boolean; + starred?: boolean; + }; + DataAnalysisSavedListV1: { + analyses?: components["schemas"]["DataAnalysisSavedEntryV1"][]; + }; + DataAnalysisSavedRequestV1: { + /** @enum {string} */ + kind: "COLUMN_PROFILE" | "TABLE_PROFILE" | "PIVOT" | "COMPARE" | "CORRELATION" | "CROSSTAB" | "SHIFT"; + /** @description Source QQQ table name; required for ad hoc export, supplied by the path for SQL. */ + tableName?: string; + /** @description Typed request matching kind. Field names, filters and dimensions use the existing analysis request contracts. */ + request: components["schemas"]["DataAnalysisColumnProfileRequestV1"] | components["schemas"]["DataAnalysisTableProfileRequestV1"] | components["schemas"]["DataAnalysisPivotRequestV1"] | components["schemas"]["DataAnalysisCompareRequestV1"] | components["schemas"]["DataAnalysisCorrelationRequestV1"] | components["schemas"]["DataAnalysisCrosstabRequestV1"] | components["schemas"]["DataAnalysisShiftRequestV1"]; + /** + * @description Required for export; ignored for SQL. + * @enum {string} + */ + format?: "csv" | "xlsx"; + }; + DataAnalysisSavedResultV1: { + /** @enum {string} */ + kind?: "COLUMN_PROFILE" | "TABLE_PROFILE" | "PIVOT" | "COMPARE" | "CORRELATION" | "CROSSTAB" | "SHIFT"; + warnings?: string[]; + columnProfile?: components["schemas"]["DataAnalysisColumnProfileV1"]; + compare?: components["schemas"]["DataAnalysisCompareV1"]; + correlation?: components["schemas"]["DataAnalysisCorrelationV1"]; + crosstab?: components["schemas"]["DataAnalysisCrosstabV1"]; + pivot?: components["schemas"]["DataAnalysisPivotV1"]; + shift?: components["schemas"]["DataAnalysisShiftV1"]; + tableProfile?: components["schemas"]["DataAnalysisTableProfileV1"]; + }; + DataAnalysisScatterRequestV1: { + /** @description Table for the scatter link; route parameter takes precedence. */ + tableName?: string | null; + /** @description Compatibility flag; scatter always returns the bounded sample. */ + exact?: boolean | null; + /** @description Current-user query filter; record locks and core field rules apply. */ + filter?: components["schemas"]["QueryFilter"]; + /** @description FULL numeric field on the x axis. */ + xField: string; + /** @description FULL numeric field on the y axis. */ + yField: string; + /** @description Maximum sample points (1 to 2000, default 2000) or kept crosstab categories per axis (1 to 20, default 20). */ + limit?: number; + }; + DataAnalysisScatterV1: { + /** @description Pairwise non-null population count; null when privacy suppresses it. */ + n?: number | null; + /** @description Number of displayed paired records. */ + sampleSize?: number | null; + /** @description Sampling method; core query currently uses a deterministic primary-key prefix. */ + sampling?: string | null; + /** @description Points. */ + points?: components["schemas"]["DataAnalysisPointV1"][] | null; + /** @description Least-squares slope, intercept and r fitted to the displayed sample. */ + trend?: components["schemas"]["DataAnalysisTrendLineV1"]; + /** @description Semantic series; category comparisons are grouped and category time series are stacked. */ + chart?: components["schemas"]["DataAnalysisChartV1"]; + }; + DataAnalysisSeriesV1: { + /** @description Name. */ + name?: string | null; + /** @description Points. */ + points?: components["schemas"]["DataAnalysisPointV1"][] | null; + } | null; + DataAnalysisShiftBucketV1: { + /** @description Value. */ + value?: unknown; + /** @description Label. */ + label?: string | null; + /** @description True when the calendar bucket end has passed in the session timezone. */ + complete?: boolean | null; + /** @description Typed metrics with exact population drills unless privacy suppresses them. */ + metrics?: components["schemas"]["DataAnalysisMetricV1"][] | null; + }; + DataAnalysisShiftRequestV1: { + /** @description Current-user query filter; record locks and core field rules apply. */ + filter?: components["schemas"]["QueryFilter"]; + /** @description FULL field whose distribution is compared over time. */ + field: string; + /** @description FULL DATE or DATE_TIME field for session-timezone calendar buckets. */ + dateField: string; + /** @description Calendar unit: HOUR, DAY, WEEK, MONTH, QUARTER or YEAR; default MONTH. */ + bucket?: string; + }; + DataAnalysisShiftV1: { + /** @description Buckets. */ + buckets?: components["schemas"]["DataAnalysisShiftBucketV1"][] | null; + /** @description Population stability index, null when inapplicable; zero shares are floored at 0.000001. */ + psi?: components["schemas"]["DataAnalysisMetricV1"]; + /** @description Plain-language result or reason the statistic is not applicable. */ + sentence?: string | null; + /** @description Semantic series; category comparisons are grouped and category time series are stacked. */ + chart?: components["schemas"]["DataAnalysisChartV1"]; + }; + DataAnalysisSignificanceV1: { + /** @description Test. */ + test?: string | null; + /** @description Statistic. */ + statistic?: number | null; + /** @description Degrees of freedom; null when undefined. */ + df?: number | null; + /** @description Two-sided p-value; p >= 0.05 is never significant. */ + pValue?: number | null; + /** @description Whether all test validity and privacy requirements hold. */ + applicable?: boolean | null; + /** @description Plain-language result or reason the statistic is not applicable. */ + sentence?: string | null; + /** @description Cramer association strength computed on the pooled contingency table; null when invalid. */ + cramersV?: number | null; + }; + DataAnalysisSqlV1: { + available?: boolean; + note?: string; + sql?: string | null; + }; + DataAnalysisStarV1: { + starred?: boolean; + }; + DataAnalysisStartRunRequestV1: { + /** + * @description COLUMN_PROFILE or TABLE_PROFILE. + * @enum {string} + */ + operation: "COLUMN_PROFILE" | "TABLE_PROFILE"; + /** @description Table name. */ + tableName: string; + /** @description Profile parameters for the selected operation, without tableName. */ + request: components["schemas"]["DataAnalysisColumnProfileRequestV1"] | components["schemas"]["DataAnalysisTableProfileRequestV1"]; + }; + DataAnalysisTableProfileRequestV1: { + /** @description Core QueryFilter JSON, identical to the table query and count endpoints. */ + filter?: components["schemas"]["QueryFilter"]; + /** @description Readable fields to include; omit for all analyzable fields on a table profile. */ + fields?: string[]; + }; + DataAnalysisTableProfileV1: { + /** @description Table name. */ + tableName?: string | null; + /** @description Core QueryFilter JSON, identical to the table query and count endpoints. */ + filter?: components["schemas"]["QueryFilter"]; + /** @description True when statistics describe a sample rather than the entire filtered population. */ + estimate?: boolean | null; + /** @description Actual number of rows in the sample, not an extrapolated count. */ + sampleRows?: number | null; + /** @description True when the row limit prevented a complete scan. */ + truncated?: boolean | null; + /** @description Number of source rows included in computation. */ + rowsScanned?: number | null; + /** + * Format: date-time + * @description As of. + */ + asOf?: string | null; + /** @description Data version. */ + dataVersion?: string | null; + /** @description Warnings. */ + warnings?: string[] | null; + /** @description Row count. */ + rowCount?: components["schemas"]["DataAnalysisMetricV1"]; + /** @description Readable fields to include; omit for all analyzable fields on a table profile. */ + fields?: components["schemas"]["DataAnalysisFieldSummaryV1"][] | null; + /** @description Heatmap. */ + heatmap?: components["schemas"]["DataAnalysisChartV1"]; + /** @description Candidate keys. */ + candidateKeys?: components["schemas"]["DataAnalysisCandidateKeyV1"][] | null; + } | null; + DataAnalysisTextProfileV1: { + /** @description Metrics. */ + metrics?: components["schemas"]["DataAnalysisMetricV1"][] | null; + /** @description Histogram. */ + histogram?: components["schemas"]["DataAnalysisValueCountV1"][] | null; + /** @description Patterns. */ + patterns?: components["schemas"]["DataAnalysisValueCountV1"][] | null; + /** @description Actual number of rows in the sample, not an extrapolated count. */ + sampleRows?: number | null; + } | null; + DataAnalysisTrendLineV1: { + /** @description Slope. */ + slope?: number | null; + /** @description Intercept. */ + intercept?: number | null; + /** @description Pearson correlation; null for insufficient data, zero variance or privacy suppression. */ + r?: number | null; + }; + DataAnalysisValueCountV1: { + /** @description Value. */ + value?: (string | number | boolean | (Record | null)) | null; + /** @description Label. */ + label?: string | null; + /** @description Count. */ + count?: number | null; + /** @description Share as a 0..1 ratio rounded to six decimals. */ + share?: number | null; + /** @description Open the matching records using this table and QueryFilter; null when suppressed. */ + drill?: components["schemas"]["DataAnalysisDrillV1"]; + } | null; + DataAnalysisWatchBucketV1: { + /** @description Calendar date or hour-start instant in the user's time zone. */ + start?: string; + value?: number | null; + categories?: string[]; + drill?: components["schemas"]["DataAnalysisDrillV1"]; + }; + DataAnalysisWatchPreviewV1: { + series?: components["schemas"]["DataAnalysisWatchBucketV1"][]; + /** @description TIME_SERIES with baseline band annotations. */ + chart?: components["schemas"]["DataAnalysisChartV1"]; + verdict?: components["schemas"]["DataAnalysisWatchVerdictV1"]; + }; + DataAnalysisWatchVerdictV1: { + /** @description False for insufficient history or privacy suppression; must not resolve an alert. */ + evaluated?: boolean; + firing?: boolean; + value?: number | null; + baseline?: number | null; + baselineLow?: number | null; + baselineHigh?: number | null; + message?: string; + drill?: components["schemas"]["DataAnalysisDrillV1"]; + }; + DbPerformanceActivityV1: { + blockingChains?: components["schemas"]["DbPerformanceBlockingChainV1"][]; + liveTextRedacted?: boolean; + sessions?: components["schemas"]["DbPerformanceSessionV1"][]; + }; + DbPerformanceBlockingChainV1: { + blockedPids?: (number | null)[]; + rootPid?: number | null; + }; + DbPerformanceErrorV1: { + error?: string | null; + }; + /** @description Supply exactly one of statementId or sql. Parameters are strings, accepted only for ANALYZE and never stored. */ + DbPerformanceExplainRequestV1: { + backend?: string | null; + /** @enum {string} */ + mode?: "PLAN" | "ANALYZE"; + parameters?: (string | null)[]; + sql?: string | null; + statementId?: number | null; + }; + DbPerformanceExplainResultV1: { + actualTotalMs?: number | null; + assistantPrompt?: string | null; + explainId?: number | null; + mode?: string | null; + planJson?: string | null; + planText?: string | null; + sqlWorkbenchUrl?: string | null; + totalCost?: number | null; + warnings?: (string | null)[]; + }; + DbPerformanceFindingV1: { + id?: number | null; + score?: number | null; + severity?: string | null; + title?: string | null; + }; + DbPerformanceLookupV1: { + fingerprint?: string | null; + matches?: components["schemas"]["DbPerformanceStatementV1"][]; + normalizedSql?: string | null; + }; + DbPerformanceOverviewV1: { + findingsBySeverity?: { + [key: string]: number | null; + }; + settings?: components["schemas"]["DbPerformanceSettingsV1"]; + snapshot?: components["schemas"]["DbPerformanceSnapshotV1"]; + topFindings?: components["schemas"]["DbPerformanceFindingV1"][]; + topStatements?: components["schemas"]["DbPerformanceStatementV1"][]; + }; + DbPerformanceSessionV1: { + application?: string | null; + blockedBy?: (number | null)[]; + blockingCount?: number | null; + fingerprint?: string | null; + liveTextRedacted?: boolean; + normalizedText?: string | null; + pid?: number | null; + /** @description Raw live SQL only with view_live_text; never persisted. */ + query?: string | null; + querySeconds?: number | null; + state?: string | null; + user?: string | null; + waitEvent?: string | null; + xactSeconds?: number | null; + }; + DbPerformanceSettingsV1: { + lastSnapshotAt?: string | null; + provider?: string | null; + statsAccess?: string | null; + statsAccessMessage?: string | null; + }; + DbPerformanceSnapshotV1: { + cacheHitRatio?: number | null; + capturedAt?: string | null; + connectionsTotal?: number | null; + deadlocks?: number | null; + id?: number | null; + maxConnections?: number | null; + statementCalls?: number | null; + statementTotalMs?: number | null; + status?: string | null; + tempBytes?: number | null; + }; + DbPerformanceStatementV1: { + calls24h?: number | null; + historyPath?: string | null; + hitRatio?: number | null; + id?: number | null; + meanMs24h?: number | null; + /** @description Normalized SQL, truncated to 300 characters. */ + queryText?: string | null; + shareOfDbTime24h?: number | null; + totalMs24h?: number | null; + }; + /** @description Concatenated acknowledgement previews; type is 997, 999, TA1, CONTRL, NONE or MIXED. text is null for PHI. */ + EdiAckV1: { + text?: string | null; + type?: string | null; + }; + /** @description Direct QQQ association and its target fields. */ + EdiAssociationV1: { + fields?: components["schemas"]["EdiFieldV1"][]; + label?: string | null; + name?: string | null; + table?: string | null; + }; + /** @description Only differing records are returned. Both lists are empty for PHI. */ + EdiDiffV1: { + againstExpected?: components["schemas"]["EdiDifferenceV1"][]; + againstPreviousRevision?: components["schemas"]["EdiDifferenceV1"][]; + }; + /** @description One document comparison; documentIndex is zero based. */ + EdiDifferenceV1: { + after?: { + [key: string]: unknown; + } | null; + /** @description Expected JSON or a previous mapped record. */ + before?: unknown; + documentIndex?: number | null; + }; + /** @description Element or composite component; codes contain at most 200 active codes in lexical order. */ + EdiElementV1: { + codeListId?: number | null; + codes?: (string | null)[]; + component?: number | null; + id?: string | null; + maxLength?: number | null; + minLength?: number | null; + name?: string | null; + position?: number | null; + type?: string | null; + usage?: string | null; + }; + /** @description Deprecated since 1.1.0: errors use BasicErrorResponseV1. */ + EdiErrorV1: { + error?: string | null; + }; + /** @description QQQ target field metadata. */ + EdiFieldV1: { + label?: string | null; + name?: string | null; + possibleValueSourceName?: string | null; + required?: boolean; + type?: string | null; + }; + /** @description Value-free diagnostic. PHI messages are generic; only positions and codes are retained. */ + EdiFindingV1: { + code?: string | null; + elementPosition?: number | null; + loopId?: string | null; + message?: string | null; + segmentId?: string | null; + segmentPosition?: number | null; + severity?: string | null; + snipLevel?: number | null; + }; + /** @description Ordered guide tree. Root segments are outside loops; nested loops retain parent scope. */ + EdiGuideTreeV1: { + loops?: components["schemas"]["EdiLoopV1"][]; + segments?: components["schemas"]["EdiSegmentV1"][]; + }; + /** @description Guide loop, nested within its parent; repeat is the maximum occurrence count. */ + EdiLoopV1: { + id?: string | null; + loops?: components["schemas"]["EdiLoopV1"][]; + repeat?: number | null; + segments?: components["schemas"]["EdiSegmentV1"][]; + }; + /** @description Counts of wire interchanges, groups and documents. */ + EdiParseV1: { + documents?: number | null; + groups?: number | null; + interchanges?: number | null; + }; + /** @description mapId is required. Supply exactly one of sampleId or sampleBase64. Uploads are at most 5 MiB decoded, stored encrypted. ruleOverrides replaces the whole rule set in memory. CURRENT (default) uses the newest active guide in the pinned guide family; ORIGINAL uses the pinned guide. */ + EdiPreviewRequestV1: { + /** @enum {string|null} */ + guideRevision?: "CURRENT" | "ORIGINAL" | null; + mapId?: number | null; + ruleOverrides?: components["schemas"]["EdiRuleV1"][] | null; + /** Format: byte */ + sampleBase64?: string | null; + sampleId?: number | null; + sampleName?: string | null; + }; + /** @description Parse, validate, acknowledge and map without target writes. PHI suppresses result, ack text, and both diffs. */ + EdiPreviewV1: { + ack?: components["schemas"]["EdiAckV1"]; + diff?: components["schemas"]["EdiDiffV1"]; + findings?: components["schemas"]["EdiFindingV1"][]; + parse?: components["schemas"]["EdiParseV1"]; + phiSuppressed?: boolean; + result?: components["schemas"]["EdiResultV1"]; + }; + /** @description Field values and recursively associated records. Values use the target table field types. */ + EdiRecordV1: { + associations?: { + [key: string]: components["schemas"]["EdiRecordV1"][]; + }; + values?: { + [key: string]: unknown; + }; + }; + /** @description Mapped records in document order; no target writes. */ + EdiResultV1: { + records?: components["schemas"]["EdiRecordV1"][]; + }; + /** @description Correlate errors using zero-based index, optional id and sequence. */ + EdiRuleErrorsV1: { + errors?: (string | null)[]; + id?: number | null; + index?: number | null; + sequence?: number | null; + }; + /** @description Map rule. id is optional for unsaved rules. transformArgs is a JSON object encoded as a string, as in core table CRUD. */ + EdiRuleV1: { + condition?: string | null; + defaultValue?: string | null; + ediPath?: string | null; + id?: number | null; + qqqPath?: string | null; + required?: boolean | null; + sequence?: number | null; + transform?: string | null; + transformArgs?: string | null; + }; + /** @description Segment definition in guide sequence order. */ + EdiSegmentV1: { + elements?: components["schemas"]["EdiElementV1"][]; + id?: string | null; + max?: number | null; + min?: number | null; + name?: string | null; + position?: string | null; + usage?: string | null; + }; + /** @description Target metadata visible to the caller, current rules and registered transforms. */ + EdiTargetV1: { + associations?: components["schemas"]["EdiAssociationV1"][]; + fields?: components["schemas"]["EdiFieldV1"][]; + rules?: components["schemas"]["EdiRuleV1"][]; + table?: string | null; + transforms?: components["schemas"]["EdiTransformV1"][]; + }; + /** @description Registered transform and JSON Schema describing its string-valued arguments. */ + EdiTransformV1: { + /** @description JSON Schema: type, properties, required and additionalProperties. All transform arguments are strings. */ + argumentSchema?: { + [key: string]: unknown; + }; + name?: string | null; + }; + /** @description rules is required and may be empty; rules are never persisted. */ + EdiValidateRequestV1: { + rules?: components["schemas"]["EdiRuleV1"][]; + }; + /** @description One result per submitted rule, including rules with no errors. */ + EdiValidationV1: { + rules?: components["schemas"]["EdiRuleErrorsV1"][]; + }; + /** @description What QA capture means for the signed-in user. Clients that see enabled=false do nothing else. */ + QaCaptureCapabilityV1: { + /** @description CSS selectors to blur in recordings; empty when not enabled. */ + blurSelectors?: string[]; + /** @description Whether the user can file a report (Report a bug). */ + canReport?: boolean; + context?: components["schemas"]["QaCaptureContextV1"]; + cspOrigins?: components["schemas"]["QaCaptureCspOriginsV1"]; + /** @description Whether capture is on for this user. */ + enabled?: boolean; + /** @description The provider name (for example jam); null when not enabled. */ + provider?: string | null; + /** @description Provider settings; null when not enabled. */ + providerConfig?: components["schemas"]["QaCaptureProviderConfigV1"] | null; + qaMode?: components["schemas"]["QaCaptureQaModeV1"]; + /** + * @description Why capture is on or off. + * @enum {string} + */ + reason?: "AUDIENCE" | "QA_MODE" | "OFF" | "NOT_CONFIGURED" | "NO_ACCESS" | "QA_MODE_OFF"; + /** @description The QA reports screen, only when the user can view reports. Clients follow it, never build it. */ + reportsHref?: string | null; + /** @description The response header carrying the request id (X-Request-Id). */ + requestIdHeader?: string; + /** @description Redaction rules; null when not enabled. */ + sanitizer?: components["schemas"]["QaCaptureSanitizerV1"] | null; + }; + /** @description Server context for capture metadata. */ + QaCaptureContextV1: { + /** @description The backend build version. */ + backendVersion?: string | null; + /** @description The environment name. */ + environment?: string; + /** @description The serving node. */ + node?: string | null; + }; + /** @description Content-Security-Policy origins the provider needs; empty when not enabled. */ + QaCaptureCspOriginsV1: { + /** @description connect-src sources. */ + connectSrc?: string[]; + /** @description frame-src sources. */ + frameSrc?: string[]; + /** @description script-src sources. */ + scriptSrc?: string[]; + }; + /** @description An error. */ + QaCaptureErrorV1: { + /** @description What went wrong. */ + error?: string; + }; + /** @description Provider settings for the browser. For Jam: teamId, recordingLinkId and the script URLs. */ + QaCaptureProviderConfigV1: { + /** @description A reusable recording link id for in-app Report a bug; null when none is set. */ + recordingLinkId?: string | null; + /** @description The provider's scripts, in load order. */ + scriptUrls?: string[]; + /** @description The provider team id. */ + teamId?: string; + }; + /** @description The user's self-serve QA mode switch. */ + QaCaptureQaModeV1: { + /** @description Whether the user's QA mode is on. */ + active?: boolean; + /** @description Whether the user can switch QA mode (self-serve mode and the qa_capture.use_qa_mode permission). */ + available?: boolean; + /** @description The user preference section holding the switch; null when unavailable. */ + preferenceSection?: string | null; + }; + /** @description A new QA report. Only pageUrl is required. */ + QaCaptureReportRequestV1: { + /** @description The current app. */ + appName?: string | null; + /** @description The client build version. */ + frontendVersion?: string | null; + /** @description The page the user is on; sanitizer query parameters are removed. */ + pageUrl?: string; + /** @description The current process. */ + processName?: string | null; + /** @description The current record id. */ + recordId?: string | null; + /** @description Recent X-Request-Id values (at most 50 are kept, each at most 128 characters). */ + requestIds?: string[] | null; + /** @description The current table. */ + tableName?: string | null; + /** @description A short title; defaults to the table and record, process, app or page. */ + title?: string | null; + /** @description The browser user agent. */ + userAgent?: string | null; + /** @description The viewport size, for example 1440x900. */ + viewport?: string | null; + }; + /** @description The created report and how to open the provider's recorder for it. */ + QaCaptureReportResultV1: { + /** @description The report id. */ + id?: number; + /** @description Query parameters that open the recorder (Jam: jam-recording, jam-title, jam-reference); null when no recording link is configured. */ + recordingParams?: { + [key: string]: string; + } | null; + /** @description The report reference (qa-), matched by the provider webhook. */ + reference?: string; + /** @description The report title. */ + title?: string; + }; + /** @description Redaction rules applied in the browser before anything is sent to the provider. */ + QaCaptureSanitizerV1: { + /** @description JSON keys (any depth, case-insensitive) and form fields replaced by the redaction text. */ + bodyFieldNames?: string[]; + /** @description Same-origin path prefixes whose request and response bodies are dropped. */ + dropPathPrefixes?: string[]; + /** @description Lowercase header names deleted from request and response headers. */ + headerNames?: string[]; + /** @description Query parameters redacted in request URLs and the page URL. */ + queryParamNames?: string[]; + /** @description The replacement text. */ + redaction?: string; + /** @description JavaScript RegExp sources applied with flag g to bodies and console arguments. */ + valuePatterns?: string[]; + }; + /** @description Deprecated since 1.1.0: errors use BasicErrorResponseV1. */ + QuickSearchErrorV1: { + /** @description Framework error message. */ + error?: string; + }; + QuickSearchIndexStatusV1: { + /** + * Format: date-time + * @description Saved validation completion; null when validation counts are unavailable. + */ + countsCheckedAt?: string | null; + /** + * Format: int64 + * @description Saved validation document count, else last indexing run count; not live. + */ + documentCount?: number | null; + /** @description Whether this index is enabled. */ + enabled?: boolean; + /** @description Persisted indexing error; null when absent. */ + lastError?: string | null; + /** + * Format: date-time + * @description Newest successful basepull/full-reindex/reconcile watermark. + */ + lastSuccessfulSync?: string | null; + /** @description Persisted real-time indexing error count. */ + realTimeErrorCount?: number | null; + /** + * Format: int64 + * @description Source count from saved IndexValidator report; null without validation. + */ + sourceCount?: number | null; + /** @description Persisted indexing state, such as ACTIVE or NEEDS_REINDEX. */ + status?: string | null; + /** @description Indexed source table metadata name. */ + tableName?: string; + }; + QuickSearchStatusV1: { + /** @description Cluster health counter; null when unavailable. */ + activeShards?: number | null; + /** @description Counts are lower bounds when more than 1000 backlog rows exist. */ + backlogTruncated?: boolean; + /** + * Format: date-time + * @description Snapshot completion time; remains unchanged on cache hits. + */ + checkedAt?: string; + /** @description OpenSearch health color; null when unknown. */ + clusterHealth?: string | null; + /** @description Whether OpenSearch answered; null when not probed. */ + clusterReachable?: boolean | null; + /** @description Exhausted failed events, from the same bounded backlog read. */ + exhausted?: number | null; + /** @description Quick Search home link, including the configured metadata prefix. */ + homeHref?: string; + /** @description At most 100 persisted index rows, ordered by id. */ + indexes?: components["schemas"]["QuickSearchIndexStatusV1"][]; + /** @description Indexing is paused; search can still serve. */ + indexingPaused?: boolean | null; + /** @description Last known indexing/search error or snapshot failure; null when absent. */ + lastError?: string | null; + /** + * Format: date-time + * @description Newest successful indexing watermark; not a guarantee all tables are current. + */ + lastSuccessfulSync?: string | null; + /** @description Cluster health counter; null when unavailable. */ + nodes?: number | null; + /** @description Pending and awaiting-reindex failed events, from at most 1000 backlog rows. */ + pending?: number | null; + /** @description Sizing or applying the index replicas failed at startup; null when not attempted. */ + replicaSettingsFailed?: boolean | null; + /** + * @description Overall availability; incomplete diagnostics are DEGRADED. + * @enum {string} + */ + state?: "OK" | "DEGRADED" | "DOWN" | "DISABLED"; + /** @description More than 100 index rows exist. */ + tablesTruncated?: boolean; + /** @description number_of_replicas Quick Search applies to its index; null when unknown or not managed (Serverless). */ + targetReplicas?: number | null; + /** @description Unassigned shards when every primary is active (all are replicas); null when unknown or a primary is not active. */ + unassignedReplicaShards?: number | null; + /** @description Cluster health counter; null when unavailable. */ + unassignedShards?: number | null; + }; + QuickSearchSuggestGroupV1: { + /** @description An extra accessible item was found in the bounded batch. False does not prove the index has no further matches. */ + hasMore?: boolean; + /** @description At most limitPerTable accessible items in per-table relevance order. */ + items?: components["schemas"]["QuickSearchSuggestItemV1"][]; + /** @description Source table label, falling back to its metadata name. */ + tableLabel?: string; + /** @description Source table metadata name. */ + tableName?: string; + }; + QuickSearchSuggestItemV1: { + /** @description Filtered record label, falling back to tableLabel #recordId when blank. */ + label?: string; + /** @description Source record primary key. */ + recordId?: string; + /** @description Already-filtered result subtitle; null when absent. */ + subtitle?: string | null; + }; + QuickSearchSuggestV1: { + /** @description Readable tables ordered by best accessible score; at most maxTables. */ + groups?: components["schemas"]["QuickSearchSuggestGroupV1"][]; + /** @description Search term after trimming and collapsing whitespace. */ + query?: string; + /** @description More tables had accessible hits than maxTables. */ + truncated?: boolean; + }; + ReleaseNotesErrorV1: { + /** @description What went wrong. */ + error?: string; + }; + ReleaseNotesItemV1: { + /** + * @description Item category. + * @enum {string} + */ + category?: "NEW" | "IMPROVED" | "FIXED" | "SECURITY" | "REMOVED"; + /** @description Category label, e.g. New. */ + categoryLabel?: string; + /** @description Optional app path or https link. */ + linkUrl?: string | null; + /** @description Optional screenshot URL. */ + screenshotUrl?: string | null; + /** @description Customer-facing text. */ + text?: string; + }; + ReleaseNotesLatestV1: { + /** @description Release id. */ + id?: number; + /** @description When it was published (ISO-8601). */ + publishedAt?: string; + /** @description Release title. */ + title?: string; + /** @description Application version. */ + version?: string; + }; + ReleaseNotesReleaseV1: { + /** @description Release id. */ + id?: number; + /** @description Published after the user last looked. */ + isNew?: boolean; + /** @description Included items in category order. */ + items?: components["schemas"]["ReleaseNotesItemV1"][]; + /** @description When it was published (ISO-8601). */ + publishedAt?: string; + /** @description Short summary. */ + summary?: string | null; + /** @description Release title. */ + title?: string; + /** @description Application version. */ + version?: string; + }; + ReleaseNotesReleasesV1: { + /** @description When the user last marked What's new as seen. */ + lastSeenAt?: string | null; + /** @description This page of releases, newest first. */ + releases?: components["schemas"]["ReleaseNotesReleaseV1"][]; + /** @description Visible published releases. */ + total?: number; + /** @description Releases new to the user. */ + unreadCount?: number; + }; + ReleaseNotesSeenV1: { + /** @description Always 0 after marking seen. */ + unreadCount?: number; + }; + ReleaseNotesSummaryV1: { + /** @description The newest visible release, or null. */ + latest?: components["schemas"]["ReleaseNotesLatestV1"]; + /** @description Releases new to the user. */ + unreadCount?: number; + }; + SecuredDataBreakGlassV1: { + id?: number; + reason?: string; + /** Format: date-time */ + expiresAt?: string; + scope?: string | null; + ceiling?: string; + }; + /** @description Deprecated since 1.1.0: errors use BasicErrorResponseV1. */ + SecuredDataErrorV1: { + error?: string; + }; + SecuredDataRevealAllowanceV1: { + tableName?: string; + fieldName?: string; + remainingDailyAllowance?: number | null; + }; + SecuredDataRevealOptionsResponseV1: { + reasonOptions?: string[]; + allowFreeTextReason?: boolean; + requireFreeText?: boolean; + revealMinutes?: number; + remainingDailyAllowance?: number | null; + }; + /** @description tableName, primaryKey and fieldName are required. Supply a policy reason or allowed free text; maximum 500 characters. */ + SecuredDataRevealRequestV1: { + tableName?: string; + fieldName?: string; + /** @description Record primary key (string or number). */ + primaryKey?: string | number; + reason?: string | null; + reasonText?: string | null; + }; + SecuredDataRevealResponseV1: { + /** @description Authorized raw field value. */ + value?: unknown; + displayValue?: string | null; + /** Format: date-time */ + expiresAt?: string; + revealId?: number; + }; + SecuredDataStatusResponseV1: { + breakGlass?: components["schemas"]["SecuredDataBreakGlassV1"]; + revealsUsedToday?: number; + revealAllowances?: components["schemas"]["SecuredDataRevealAllowanceV1"][]; + }; + SqlWorkbenchBackendV1: { + name?: string; + label?: string; + vendor?: string | null; + dialect?: components["schemas"]["SqlWorkbenchDialectV1"]; + readOnlyCredentials?: boolean; + readOnlyEnforced?: boolean; + transactionalDdl?: boolean; + writeAllowed?: boolean; + }; + SqlWorkbenchBinaryValueV1: { + $binary?: boolean; + /** Format: int64 */ + length?: number; + hexPreview?: string; + }; + SqlWorkbenchCancelledV1: { + cancelled?: boolean; + }; + SqlWorkbenchCapabilitiesV1: { + version?: string; + canWrite?: boolean; + canShare?: boolean; + writeModeEnabled?: boolean; + limits?: components["schemas"]["SqlWorkbenchLimitsV1"]; + backends?: components["schemas"]["SqlWorkbenchBackendV1"][]; + }; + SqlWorkbenchCellV1: { + cellKey?: string; + cellType?: string; + title?: string | null; + content?: string; + backendName?: string | null; + /** Format: int64 */ + sortOrder?: number; + }; + /** @enum {string} */ + SqlWorkbenchColumnKindV1: "number" | "string" | "boolean" | "date" | "datetime" | "time" | "json" | "binary" | "array" | "other"; + SqlWorkbenchColumnV1: { + name?: string; + label?: string; + typeName?: string; + /** Format: int64 */ + jdbcType?: number; + kind?: components["schemas"]["SqlWorkbenchColumnKindV1"]; + }; + SqlWorkbenchDatabaseSchemaV1: { + name?: string; + tables?: components["schemas"]["SqlWorkbenchSchemaTableV1"][]; + }; + SqlWorkbenchDeletedV1: { + deleted?: boolean; + }; + /** @enum {string} */ + SqlWorkbenchDialectV1: "postgresql" | "mysql" | "sqlite" | "h2" | "sql"; + SqlWorkbenchEmptyRequestV1: Record; + /** @description Deprecated since 1.1.0: errors use BasicErrorResponseV1. */ + SqlWorkbenchErrorV1: { + error?: string; + }; + SqlWorkbenchExecuteRequestV1: { + backendName?: string; + sql?: string; + params?: components["schemas"]["SqlWorkbenchParametersV1"]; + mode?: string; + /** Format: int64 */ + notebookId?: number | null; + cellKey?: string | null; + /** Format: int64 */ + pageSize?: number | null; + confirmToken?: string | null; + acknowledgeRowGuard?: boolean; + executionUuid?: string | null; + }; + SqlWorkbenchExecutionV1: { + executionUuid?: string; + status?: components["schemas"]["SqlWorkbenchStatusV1"]; + mode?: string; + backendName?: string; + /** Format: int64 */ + durationMs?: number | null; + statements?: components["schemas"]["SqlWorkbenchStatementV1"][]; + columns?: components["schemas"]["SqlWorkbenchColumnV1"][]; + rows?: components["schemas"]["SqlWorkbenchRowsDataV1"]; + /** Format: int64 */ + rowCount?: number; + hasMore?: boolean; + truncated?: boolean; + truncatedReason?: string | null; + /** Format: int64 */ + rowsAffected?: number; + error?: string; + sqlState?: string | null; + dryRunSupported?: boolean; + dryRunNote?: string | null; + /** Format: int64 */ + totalAffectedRows?: number | null; + rowGuardExceeded?: boolean; + /** Format: int64 */ + rowGuardLimit?: number; + confirmToken?: string; + expiresAt?: string; + /** Format: int64 */ + previewAffectedRows?: number; + /** Format: int64 */ + actualAffectedRows?: number; + }; + SqlWorkbenchExplainRequestV1: { + backendName?: string; + sql?: string; + params?: components["schemas"]["SqlWorkbenchParametersV1"]; + analyze?: boolean; + }; + SqlWorkbenchExplainV1: { + executionUuid?: string; + status?: components["schemas"]["SqlWorkbenchStatusV1"]; + mode?: string; + backendName?: string; + dialect?: components["schemas"]["SqlWorkbenchDialectV1"]; + analyze?: boolean; + plan?: components["schemas"]["SqlWorkbenchPlanNodeV1"]; + raw?: string; + error?: string; + sqlState?: string | null; + /** Format: int64 */ + durationMs?: number | null; + }; + /** Format: binary */ + SqlWorkbenchExportFileV1: string; + /** @description Rows keyed by unique column labels, with duplicate labels suffixed. */ + SqlWorkbenchExportJsonV1: { + [key: string]: components["schemas"]["SqlWorkbenchValueV1"]; + }[]; + SqlWorkbenchFreeObjectV1: { + [key: string]: unknown; + }; + SqlWorkbenchHistoryEntryV1: { + executionUuid?: string; + backendName?: string; + mode?: string; + status?: string; + sqlText?: string; + /** Format: int64 */ + notebookId?: number | null; + cellKey?: string | null; + startTime?: string | null; + /** Format: int64 */ + durationMs?: number | null; + /** Format: int64 */ + rowsReturned?: number | null; + /** Format: int64 */ + rowsAffected?: number | null; + errorMessage?: string | null; + }; + SqlWorkbenchHistoryV1: { + executions?: components["schemas"]["SqlWorkbenchHistoryEntryV1"][]; + }; + SqlWorkbenchLimitsV1: { + /** Format: int64 */ + maxRows?: number; + /** Format: int64 */ + pageSize?: number; + /** Format: int64 */ + maxPageSize?: number; + /** Format: int64 */ + maxResultBytes?: number; + /** Format: int64 */ + statementTimeoutSeconds?: number; + /** Format: int64 */ + writeStatementTimeoutSeconds?: number; + /** Format: int64 */ + maxAffectedRowsWithoutAcknowledgement?: number; + /** Format: int64 */ + maxAffectedRows?: number; + /** Format: int64 */ + maxSqlLength?: number; + /** Format: int64 */ + maxStatementsPerRun?: number; + }; + SqlWorkbenchNotebookContentV1: { + title?: string; + description?: string | null; + defaultBackendName?: string | null; + parameters?: components["schemas"]["SqlWorkbenchNotebookParameterV1"][]; + cells?: components["schemas"]["SqlWorkbenchCellV1"][]; + }; + SqlWorkbenchNotebookParameterV1: { + name?: string; + type?: string; + defaultValue?: string | null; + label?: string | null; + }; + SqlWorkbenchNotebookRequestV1: { + title?: string; + description?: string | null; + defaultBackendName?: string | null; + parameters?: components["schemas"]["SqlWorkbenchNotebookParameterV1"][]; + cells?: components["schemas"]["SqlWorkbenchCellV1"][]; + comment?: string; + }; + SqlWorkbenchNotebookSummaryV1: { + /** Format: int64 */ + id?: number; + title?: string; + description?: string | null; + visibility?: string; + ownerUserId?: string; + ownerName?: string | null; + defaultBackendName?: string | null; + /** Format: int64 */ + currentVersion?: number; + canEdit?: boolean; + createDate?: string | null; + modifyDate?: string | null; + }; + SqlWorkbenchNotebookV1: { + /** Format: int64 */ + id?: number; + title?: string; + description?: string | null; + visibility?: string; + ownerUserId?: string; + ownerName?: string | null; + defaultBackendName?: string | null; + /** Format: int64 */ + currentVersion?: number; + canEdit?: boolean; + createDate?: string | null; + modifyDate?: string | null; + parameters?: components["schemas"]["SqlWorkbenchNotebookParameterV1"][]; + cells?: components["schemas"]["SqlWorkbenchCellV1"][]; + }; + SqlWorkbenchNotebooksV1: { + notebooks?: components["schemas"]["SqlWorkbenchNotebookSummaryV1"][]; + }; + /** @description Named SQL parameter values. JSON decimals are parsed exactly as BigDecimal. */ + SqlWorkbenchParametersV1: { + [key: string]: unknown; + }; + SqlWorkbenchPlanNodeV1: { + label?: string; + detail?: string | null; + startupCost?: number | null; + totalCost?: number | null; + /** Format: int64 */ + planRows?: number | null; + actualTimeMs?: number | null; + /** Format: int64 */ + actualRows?: number | null; + /** Format: int64 */ + loops?: number | null; + extra?: components["schemas"]["SqlWorkbenchFreeObjectV1"]; + children?: components["schemas"]["SqlWorkbenchPlanNodeV1"][]; + }; + SqlWorkbenchPublishRequestV1: { + shared?: boolean; + }; + SqlWorkbenchQqqFieldV1: { + name?: string; + label?: string | null; + sqlName?: string; + type?: string | null; + }; + SqlWorkbenchQqqTableV1: { + name?: string; + label?: string | null; + sqlName?: string; + fields?: components["schemas"]["SqlWorkbenchQqqFieldV1"][]; + }; + SqlWorkbenchRowsDataV1: components["schemas"]["SqlWorkbenchValueV1"][][]; + SqlWorkbenchRowsV1: { + executionUuid?: string; + columns?: components["schemas"]["SqlWorkbenchColumnV1"][]; + rows?: components["schemas"]["SqlWorkbenchRowsDataV1"]; + /** Format: int64 */ + offset?: number; + /** Format: int64 */ + rowCount?: number; + truncated?: boolean; + truncatedReason?: string | null; + }; + SqlWorkbenchSchemaColumnV1: { + name?: string; + typeName?: string; + nullable?: boolean; + }; + SqlWorkbenchSchemaTableV1: { + name?: string; + type?: string; + columns?: components["schemas"]["SqlWorkbenchSchemaColumnV1"][]; + }; + SqlWorkbenchSchemaV1: { + backendName?: string; + dialect?: components["schemas"]["SqlWorkbenchDialectV1"]; + schemas?: components["schemas"]["SqlWorkbenchDatabaseSchemaV1"][]; + truncated?: boolean; + keywords?: string[]; + functions?: string[]; + qqqTables?: components["schemas"]["SqlWorkbenchQqqTableV1"][]; + cachedAt?: string; + }; + SqlWorkbenchSnapshotRequestV1: { + executionUuid?: string; + cellKey?: string; + label?: string | null; + }; + SqlWorkbenchSnapshotResultV1: { + columns?: components["schemas"]["SqlWorkbenchColumnV1"][]; + rows?: components["schemas"]["SqlWorkbenchRowsDataV1"]; + }; + SqlWorkbenchSnapshotV1: { + /** Format: int64 */ + id?: number; + cellKey?: string | null; + executionUuid?: string | null; + label?: string | null; + backendName?: string | null; + /** Format: int64 */ + rowCount?: number; + truncated?: boolean; + createDate?: string | null; + result?: components["schemas"]["SqlWorkbenchSnapshotResultV1"]; + }; + SqlWorkbenchSnapshotsV1: { + snapshots?: components["schemas"]["SqlWorkbenchSnapshotV1"][]; + }; + /** @enum {string} */ + SqlWorkbenchStatementKindV1: "READ" | "EXPLAIN_ANALYZE" | "WRITE" | "DDL" | "FORBIDDEN"; + SqlWorkbenchStatementV1: { + /** Format: int64 */ + index?: number; + kind?: components["schemas"]["SqlWorkbenchStatementKindV1"]; + leadingKeyword?: string | null; + text?: string; + /** Format: int64 */ + affectedRows?: number | null; + }; + /** @enum {string} */ + SqlWorkbenchStatusV1: "SUCCEEDED" | "FAILED" | "TIMED_OUT" | "CANCELLED" | "REJECTED" | "PREVIEW" | "DRIFTED"; + /** @description JSON-safe JDBC value; null, scalar, binary preview, nested array or vendor JSON object. */ + SqlWorkbenchValueV1: (string | null) | number | boolean | components["schemas"]["SqlWorkbenchBinaryValueV1"] | unknown[] | components["schemas"]["SqlWorkbenchFreeObjectV1"]; + SqlWorkbenchVersionSummaryV1: { + /** Format: int64 */ + versionNumber?: number; + savedByName?: string | null; + comment?: string | null; + createDate?: string; + }; + SqlWorkbenchVersionV1: { + /** Format: int64 */ + versionNumber?: number; + savedByName?: string | null; + comment?: string | null; + createDate?: string; + notebook?: components["schemas"]["SqlWorkbenchNotebookContentV1"]; + }; + SqlWorkbenchVersionsV1: { + versions?: components["schemas"]["SqlWorkbenchVersionSummaryV1"][]; + }; }; responses: never; parameters: never; @@ -11723,4 +16722,10424 @@ export interface operations { }; }; }; + getHealthSummary: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HealthSummaryV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getHealthComponentsByName: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Stable health check or component name. */ + name: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HealthComponentV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getHealthChecksByNameHistory: { + parameters: { + query?: { + /** @description limit is capped at 500; from/to are inclusive ISO-8601 instants. */ + from?: string; + /** @description limit is capped at 500; from/to are inclusive ISO-8601 instants. */ + to?: string; + /** @description limit is capped at 500; from/to are inclusive ISO-8601 instants. */ + limit?: number; + }; + header?: never; + path: { + /** @description Stable health check or component name. */ + name: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HealthHistoryV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postHealthChecksByNameRun: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Stable health check or component name. */ + name: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HealthRunV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + alertsInboxSummary: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AlertsInboxSummaryV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + alertsInbox: { + parameters: { + query?: { + /** @description all or unread; other values behave as all. */ + status?: string; + /** @description Case-insensitive category filter. */ + category?: string; + /** @description Case-insensitive severity filter. */ + severity?: string; + /** @description Default 0; negatives clamp to 0; malformed values use the default. */ + offset?: number; + /** @description Default 25; clamped to 1..100; malformed values use the default. */ + limit?: number; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AlertsInboxPageV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + alertsInboxRead: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AlertsInboxTargetV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AlertsMutationResultV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + alertsInboxUnread: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AlertsUnreadTargetV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AlertsMutationResultV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + alertsInboxDismiss: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AlertsInboxTargetV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AlertsMutationResultV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + alertsRecordPanel: { + parameters: { + query: { + /** @description Parent table name. */ + tableName: string; + /** @description Parent record key. */ + recordId: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AlertsRecordPanelV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getAssistantConfig: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssistantConfigResponseV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description No access to the assistant */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (or not the user's own) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Already finished or decided */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Budget or rate limit */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Disabled, not configured, or the kill switch is on */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getAssistantConversations: { + parameters: { + query?: { + /** @description ARCHIVED for archived conversations; active ones by default. */ + status?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssistantConversationListResponseV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description No access to the assistant */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (or not the user's own) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Already finished or decided */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Budget or rate limit */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Disabled, not configured, or the kill switch is on */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postAssistantConversations: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": { + title?: string; + /** @description route, tableName, recordId, filter, selectedIds. */ + context?: { + [key: string]: unknown; + }; + }; + }; + }; + responses: { + /** @description Successful Response */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssistantConversationV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description No access to the assistant */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (or not the user's own) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Already finished or decided */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Budget or rate limit */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Disabled, not configured, or the kill switch is on */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getAssistantConversationsById: { + parameters: { + query?: { + /** @description Only messages older than this message id. */ + before?: number; + /** @description Page size (default 50, at most 200). */ + limit?: number; + }; + header?: never; + path: { + /** @description The conversation id. */ + id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssistantConversationDetailResponseV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description No access to the assistant */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (or not the user's own) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Already finished or decided */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Budget or rate limit */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Disabled, not configured, or the kill switch is on */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + deleteAssistantConversationsById: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The conversation id. */ + id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Done (no body) */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description No access to the assistant */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (or not the user's own) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Already finished or decided */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Budget or rate limit */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Disabled, not configured, or the kill switch is on */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + patchAssistantConversationsById: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The conversation id. */ + id: number; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": { + title?: string; + pinned?: boolean; + /** @description ACTIVE or ARCHIVED. */ + status?: string; + /** @description Since 1.6.0: true sets unreadCount to 0 (the user watched the reply stream in). Only true is accepted. */ + read?: boolean; + }; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssistantConversationV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description No access to the assistant */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (or not the user's own) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Already finished or decided */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Budget or rate limit */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Disabled, not configured, or the kill switch is on */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postAssistantConversationsByIdTurns: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The conversation id. */ + id: number; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": { + /** @description The user's message. */ + text?: string; + /** @description Where the user is in the app: route, tableName, recordId, filter, selectedIds, and attachments (at most 5 of {uploadRef, fileName}, the user's own uploads; their content is read for this question, as untrusted data). */ + pageContext?: { + [key: string]: unknown; + }; + /** @description supersede or concurrent (case-insensitive); defaults to the host configuration. */ + concurrency?: string; + }; + }; + }; + responses: { + /** @description The turn's events, until message.end */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/event-stream": components["schemas"]["AssistantTurnEventV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description No access to the assistant */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (or not the user's own) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Already finished or decided */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Budget or rate limit */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Disabled, not configured, or the kill switch is on */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getAssistantTurnsByTurnIdEvents: { + parameters: { + query?: { + /** @description The last sequence number already received (0 for all). */ + after?: number; + }; + header?: never; + path: { + /** @description The turn id. */ + turnId: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description The turn's events after `after`, until message.end */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/event-stream": components["schemas"]["AssistantTurnEventV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description No access to the assistant */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (or not the user's own) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Already finished or decided */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Budget or rate limit */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Disabled, not configured, or the kill switch is on */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postAssistantTurnsByTurnIdCancel: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The turn id. */ + turnId: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssistantStatusResponseV1"]; + }; + }; + /** @description Legacy replica: cancellation accepted */ + 202: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssistantStatusResponseV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description No access to the assistant */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (or not the user's own) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Already finished or decided */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Budget or rate limit */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Disabled, not configured, or the kill switch is on */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getAssistantTurnsActive: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssistantActiveTurnsResponseV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description No access to the assistant */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (or not the user's own) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Already finished or decided */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Budget or rate limit */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Disabled, not configured, or the kill switch is on */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postAssistantMessagesByIdFeedback: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The assistant message id. */ + id: number; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": { + /** @description 1 or -1. */ + rating?: number; + reason?: string; + comment?: string; + }; + }; + }; + responses: { + /** @description Done (no body) */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description No access to the assistant */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (or not the user's own) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Already finished or decided */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Budget or rate limit */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Disabled, not configured, or the kill switch is on */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getAssistantActionsById: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The pending action id. */ + id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssistantActionV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description No access to the assistant */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (or not the user's own) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Already finished or decided */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Budget or rate limit */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Disabled, not configured, or the kill switch is on */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postAssistantActionsByIdConfirm: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The pending action id. */ + id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssistantActionV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description No access to the assistant */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (or not the user's own) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Already finished or decided */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Budget or rate limit */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Disabled, not configured, or the kill switch is on */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postAssistantActionsByIdReject: { + parameters: { + query?: never; + header?: never; + path: { + /** @description The pending action id. */ + id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssistantActionV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description No access to the assistant */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (or not the user's own) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Already finished or decided */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Budget or rate limit */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Disabled, not configured, or the kill switch is on */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getAssistantAccess: { + parameters: { + query?: { + /** @description Only this table. */ + table?: string; + /** @description Only the tables this text mentions. */ + prompt?: string; + /** @description Attribute this request to an owned turn. */ + turnId?: number; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssistantAccessResponseV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description No access to the assistant */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (or not the user's own) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Already finished or decided */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Budget or rate limit */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Disabled, not configured, or the kill switch is on */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postAssistantClientErrors: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AssistantClientErrorReportV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 202: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AssistantClientErrorResponseV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description No access to the assistant */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (or not the user's own) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Already finished or decided */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Budget or rate limit */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Disabled, not configured, or the kill switch is on */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationPresence: { + parameters: { + query: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationPresenceSnapshotV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitCollaborationPresence: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationPresenceRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationPresenceSnapshotV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + deleteQbitCollaborationPresence: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationPresenceLeaveV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationMutationResultV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationFavorites: { + parameters: { + query?: { + /** @description Maximum items to return, from 1 to 100; default 20. */ + limit?: number; + /** @description Opaque nextCursor returned by the previous page; omit for the first page. */ + cursor?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationFavoriteListV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + putQbitCollaborationFavorites: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationTargetRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationMutationResultV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + deleteQbitCollaborationFavorites: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationTargetRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationMutationResultV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationRecents: { + parameters: { + query?: { + /** @description Maximum items to return, from 1 to 100; default 20. */ + limit?: number; + /** @description Opaque nextCursor returned by the previous page; omit for the first page. */ + cursor?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationRecentListV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitCollaborationRecents: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationTargetRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationMutationResultV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + patchQbitCollaborationFavoritesOrder: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationFavoriteOrderRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationMutationResultV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationRecordsByTableByPkAttachments: { + parameters: { + query?: { + /** @description Maximum items to return, from 1 to 100; default 20. */ + limit?: number; + /** @description Opaque nextCursor returned by the previous page; omit for the first page. */ + cursor?: string; + }; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationAttachmentListV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitCollaborationRecordsByTableByPkAttachments: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "multipart/form-data": components["schemas"]["CollaborationAttachmentUploadRequestV1"]; + }; + }; + responses: { + /** @description Uploaded attachment */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationAttachmentV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationAttachmentsByIdDownload: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Collaboration object identifier. */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationDownloadV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationAttachmentsByIdPreview: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Collaboration object identifier. */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationDownloadV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + deleteQbitCollaborationAttachmentsById: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Collaboration object identifier. */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationMutationResultV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + patchQbitCollaborationAttachmentsById: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Collaboration object identifier. */ + id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationAttachmentPatchRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationAttachmentV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationTags: { + parameters: { + query: { + /** @description Parent table metadata name. */ + table: string; + /** @description Text to search in display names or vocabulary. */ + q?: string; + /** @description Maximum items to return, from 1 to 100; default 20. */ + limit?: number; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationTagListV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitCollaborationTags: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationTagCreateRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationTagV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationRecordsByTableByPkTags: { + parameters: { + query?: { + /** @description Maximum items to return, from 1 to 100; default 20. */ + limit?: number; + /** @description Opaque nextCursor returned by the previous page; omit for the first page. */ + cursor?: string; + }; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationTagListV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + putQbitCollaborationRecordsByTableByPkTags: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationTagApplyRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationTagListV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationRecordsByTableByPkComments: { + parameters: { + query?: { + /** @description Maximum items to return, from 1 to 100; default 20. */ + limit?: number; + /** @description Opaque nextCursor returned by the previous page; omit for the first page. */ + cursor?: string; + }; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationCommentPageV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitCollaborationRecordsByTableByPkComments: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationCommentPostRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationCommentV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + deleteQbitCollaborationCommentsById: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Collaboration object identifier. */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationMutationResultV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + patchQbitCollaborationCommentsById: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Collaboration object identifier. */ + id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationCommentEditRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationCommentV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitCollaborationCommentsByIdResolve: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Collaboration object identifier. */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationMutationResultV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitCollaborationCommentsByIdReopen: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Collaboration object identifier. */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationMutationResultV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationCommentsByIdHistory: { + parameters: { + query?: { + /** @description Maximum items to return, from 1 to 100; default 20. */ + limit?: number; + /** @description Opaque nextCursor returned by the previous page; omit for the first page. */ + cursor?: string; + }; + header?: never; + path: { + /** @description Collaboration object identifier. */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationCommentHistoryV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationMentionsCandidates: { + parameters: { + query: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + /** @description Text to search in display names or vocabulary. */ + q?: string; + /** @description Maximum items to return, from 1 to 100; default 20. */ + limit?: number; + /** @description Opaque nextCursor returned by the previous page; omit for the first page. */ + cursor?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationMentionCandidateListV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationRecordsByTableByPkFollow: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationFollowStateV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + putQbitCollaborationRecordsByTableByPkFollow: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationFollowRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationFollowStateV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + deleteQbitCollaborationRecordsByTableByPkFollow: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationFollowStateV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationRecordsByTableByPkFollowers: { + parameters: { + query?: { + /** @description Maximum items to return, from 1 to 100; default 20. */ + limit?: number; + /** @description Opaque nextCursor returned by the previous page; omit for the first page. */ + cursor?: string; + }; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationFollowerListV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationRecordsByTableByPkTimeline: { + parameters: { + query?: { + /** @description Timeline continuation token; alias for cursor. Supply only one. */ + before?: string; + /** @description Comma-separated AUDIT, ACTIVITY or activity type names (for example COMMENTED). */ + types?: string; + /** @description Maximum items to return, from 1 to 100; default 20. */ + limit?: number; + /** @description Opaque nextCursor returned by the previous page; omit for the first page. */ + cursor?: string; + }; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationTimelinePageV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationPeople: { + parameters: { + query?: { + /** @description Text to search in display names or vocabulary. */ + q?: string; + /** @description Maximum items to return, from 1 to 100; default 20. */ + limit?: number; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationPersonListV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationPeopleByUserId: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Stable directory user identity. */ + userId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationPersonV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationRecordsByTableByPkLink: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationLinkV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitCollaborationRecordsByTableByPkSharesPreview: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationShareRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationSharePreviewV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitCollaborationRecordsByTableByPkShares: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationShareRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationShareListV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitCollaborationAccessRequests: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationAccessRequestCreateRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationAccessRequestV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationAccessRequestsMine: { + parameters: { + query?: { + /** @description Maximum items to return, from 1 to 100; default 20. */ + limit?: number; + /** @description Opaque nextCursor returned by the previous page; omit for the first page. */ + cursor?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationAccessRequestListV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationRecordsByTableByPkTasks: { + parameters: { + query?: { + /** @description Include completed and cancelled tasks; default false. */ + includeDone?: boolean; + /** @description Maximum items to return, from 1 to 100; default 20. */ + limit?: number; + /** @description Opaque nextCursor returned by the previous page; omit for the first page. */ + cursor?: string; + }; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationTaskListV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitCollaborationRecordsByTableByPkTasks: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationTaskCreateRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationTaskV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + patchQbitCollaborationTasksById: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Collaboration object identifier. */ + id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationTaskPatchRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationTaskV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationTasksMine: { + parameters: { + query?: { + /** @description Task status: OPEN (default), DONE or CANCELLED. */ + status?: string; + /** @description Maximum items to return, from 1 to 100; default 20. */ + limit?: number; + /** @description Opaque nextCursor returned by the previous page; omit for the first page. */ + cursor?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationTaskListV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + putQbitCollaborationRecordsByTableByPkAssignment: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Parent table metadata name. */ + table: string; + /** @description Parent record primary key. */ + pk: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CollaborationAssignmentRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationAssignmentV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitCollaborationMyWork: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CollaborationMyWorkV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found (including invisible parents) */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitDataAnalysisSavedByIdRun: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Owner-scoped analysis run or watch id. */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisSavedResultV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitDataAnalysisSaved: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisSavedListV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + putQbitDataAnalysisSavedByIdStar: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Owner-scoped analysis run or watch id. */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisStarV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + deleteQbitDataAnalysisSavedByIdStar: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Owner-scoped analysis run or watch id. */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisStarV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitDataAnalysisTablesByTableSql: { + parameters: { + query?: never; + header?: never; + path: { + /** @description QQQ table name to analyze. */ + table: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DataAnalysisSavedRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisSqlV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitDataAnalysisExport: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DataAnalysisSavedRequestV1"]; + }; + }; + responses: { + /** @description Analysis result file */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": components["schemas"]["DataAnalysisFileV1"]; + "text/csv": components["schemas"]["DataAnalysisFileV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitDataAnalysisSavedByIdExport: { + parameters: { + query: { + /** @description Result file format. */ + format: "csv" | "xlsx"; + }; + header?: never; + path: { + /** @description Visible saved analysis id. */ + id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Analysis result file */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": components["schemas"]["DataAnalysisFileV1"]; + "text/csv": components["schemas"]["DataAnalysisFileV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitDataAnalysisTablesByTableCapabilities: { + parameters: { + query?: never; + header?: never; + path: { + /** @description QQQ table name to analyze. */ + table: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisCapabilitiesV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitDataAnalysisTablesByTableColumnProfile: { + parameters: { + query?: never; + header?: never; + path: { + /** @description QQQ table name to analyze. */ + table: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DataAnalysisColumnProfileRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisColumnProfileV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitDataAnalysisTablesByTableDistinctValues: { + parameters: { + query?: never; + header?: never; + path: { + /** @description QQQ table name to analyze. */ + table: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DataAnalysisDistinctValuesRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisDistinctValuesPageV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitDataAnalysisTablesByTableCompare: { + parameters: { + query?: never; + header?: never; + path: { + /** @description QQQ table name to analyze. */ + table: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DataAnalysisCompareRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisCompareV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitDataAnalysisTablesByTableShift: { + parameters: { + query?: never; + header?: never; + path: { + /** @description QQQ table name to analyze. */ + table: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DataAnalysisShiftRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisShiftV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitDataAnalysisTablesByTableCorrelation: { + parameters: { + query?: never; + header?: never; + path: { + /** @description QQQ table name to analyze. */ + table: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DataAnalysisCorrelationRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisCorrelationV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitDataAnalysisTablesByTableScatter: { + parameters: { + query?: never; + header?: never; + path: { + /** @description QQQ table name to analyze. */ + table: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DataAnalysisScatterRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisScatterV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitDataAnalysisTablesByTableCrosstab: { + parameters: { + query?: never; + header?: never; + path: { + /** @description QQQ table name to analyze. */ + table: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DataAnalysisCrosstabRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisCrosstabV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitDataAnalysisWatchesByIdPreview: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Owner-scoped analysis run or watch id. */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisWatchPreviewV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitDataAnalysisTablesByTablePivot: { + parameters: { + query?: never; + header?: never; + path: { + /** @description QQQ table name to analyze. */ + table: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DataAnalysisPivotRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisPivotV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitDataAnalysisTablesByTableTableProfile: { + parameters: { + query?: never; + header?: never; + path: { + /** @description QQQ table name to analyze. */ + table: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DataAnalysisTableProfileRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisTableProfileV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitDataAnalysisTablesByTableDuplicates: { + parameters: { + query?: never; + header?: never; + path: { + /** @description QQQ table name to analyze. */ + table: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DataAnalysisDuplicatesRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisDuplicatesResultV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitDataAnalysisRuns: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DataAnalysisStartRunRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisRunStartedV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitDataAnalysisRunsByRunId: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Owner-scoped analysis run or watch id. */ + runId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DataAnalysisRunStatusV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + dbPerformanceOverview: { + parameters: { + query?: { + /** @description Configured monitored backend; defaults to the qbit backend. */ + backend?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DbPerformanceOverviewV1"]; + }; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DbPerformanceErrorV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DbPerformanceErrorV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DbPerformanceErrorV1"]; + }; + }; + }; + }; + dbPerformanceActivity: { + parameters: { + query?: { + /** @description Configured monitored backend; defaults to the qbit backend. */ + backend?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DbPerformanceActivityV1"]; + }; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DbPerformanceErrorV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DbPerformanceErrorV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DbPerformanceErrorV1"]; + }; + }; + }; + }; + dbPerformanceExplain: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DbPerformanceExplainRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DbPerformanceExplainResultV1"]; + }; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DbPerformanceErrorV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DbPerformanceErrorV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DbPerformanceErrorV1"]; + }; + }; + }; + }; + dbPerformanceLookup: { + parameters: { + query: { + /** @description Configured monitored backend; defaults to the qbit backend. */ + backend?: string; + sql: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DbPerformanceLookupV1"]; + }; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DbPerformanceErrorV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DbPerformanceErrorV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["DbPerformanceErrorV1"]; + }; + }; + }; + }; + getQbitEdiGuidesByGuideIdTree: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Positive record identifier. */ + guideId: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["EdiGuideTreeV1"]; + }; + }; + /** @description Invalid request or sample exceeds 5 MiB */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible record */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Host HTTP request size limit exceeded */ + 413: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitEdiMapsByMapIdTarget: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Positive record identifier. */ + mapId: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["EdiTargetV1"]; + }; + }; + /** @description Invalid request or sample exceeds 5 MiB */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible record */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Host HTTP request size limit exceeded */ + 413: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitEdiSandboxPreview: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["EdiPreviewRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["EdiPreviewV1"]; + }; + }; + /** @description Invalid request or sample exceeds 5 MiB */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible record */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Host HTTP request size limit exceeded */ + 413: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitEdiMapsByMapIdValidate: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Positive record identifier. */ + mapId: number; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["EdiValidateRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["EdiValidationV1"]; + }; + }; + /** @description Invalid request or sample exceeds 5 MiB */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible record */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Host HTTP request size limit exceeded */ + 413: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + qaCaptureCapability: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["QaCaptureCapabilityV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["QaCaptureErrorV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["QaCaptureErrorV1"]; + }; + }; + /** @description QA capture is not enabled for this user */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["QaCaptureErrorV1"]; + }; + }; + }; + }; + qaCaptureReportCreate: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["QaCaptureReportRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["QaCaptureReportResultV1"]; + }; + }; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["QaCaptureErrorV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["QaCaptureErrorV1"]; + }; + }; + /** @description QA capture is not enabled for this user */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["QaCaptureErrorV1"]; + }; + }; + }; + }; + getQuickSearchStatus: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["QuickSearchStatusV1"]; + }; + }; + /** @description Diagnostic rate limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Quick Search admin permission required */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQuickSearchSuggestions: { + parameters: { + query: { + /** @description Search text: trim and collapse whitespace before applying the 2..100 character range. Shorter terms return empty groups; longer terms return 400. */ + q: string; + /** @description Items per table: integer 1..10, default 5. */ + limitPerTable?: number; + /** @description Groups to return: integer 1..20, default 8. */ + maxTables?: number; + /** @description Optional comma-separated table metadata names. Unknown, disabled and unreadable tables are omitted. */ + tables?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["QuickSearchSuggestV1"]; + }; + }; + /** @description Missing q, normalized term longer than 100 characters, or invalid limits */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Session permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + releaseNotesReleases: { + parameters: { + query?: { + /** @description Releases per page (1-50, default 20). */ + limit?: number; + /** @description Releases to skip (default 0). */ + offset?: number; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReleaseNotesReleasesV1"]; + }; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReleaseNotesErrorV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReleaseNotesErrorV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + releaseNotesSummary: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReleaseNotesSummaryV1"]; + }; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReleaseNotesErrorV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReleaseNotesErrorV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + releaseNotesSeen: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReleaseNotesSeenV1"]; + }; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReleaseNotesErrorV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReleaseNotesErrorV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + postQbitSecuredDataReveal: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SecuredDataRevealRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SecuredDataRevealResponseV1"]; + }; + }; + /** @description Invalid reveal request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Reveal denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Record not found or locked */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Daily reveal cap reached */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitSecuredDataRevealOptions: { + parameters: { + query: { + tableName: string; + fieldName: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SecuredDataRevealOptionsResponseV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + getQbitSecuredDataStatus: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SecuredDataStatusResponseV1"]; + }; + }; + /** @description Bad request: a parameter or the body is invalid (code BAD_REQUEST); fieldErrors may name the fields. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not authenticated, or the session or token is invalid or expired (code UNAUTHENTICATED). Sign in again, or refresh the token. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description The user (or the credential's scope) may not do this (code PERMISSION_DENIED). */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Not found, or not visible to this user (code NOT_FOUND). */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Conflict with the current state, e.g. an edit conflict or an invalid transition (code CONFLICT). */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchGetCapabilities: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchCapabilitiesV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchGetSchema: { + parameters: { + query?: { + /** @description True to bypass the schema cache; default false. */ + refresh?: boolean; + }; + header?: never; + path: { + /** @description Configured target backend name. */ + backendName: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchSchemaV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchExecute: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": components["schemas"]["SqlWorkbenchExecuteRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchExecutionV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchExplain: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": components["schemas"]["SqlWorkbenchExplainRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchExplainV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchGetRows: { + parameters: { + query?: { + /** @description Rows to skip; default zero; negative values become zero. */ + offset?: number; + /** @description Page size; nonpositive or absent uses the default. Rows cap at maxPageSize; history caps at 200 (default 50). */ + limit?: number; + /** @description Optional zero-based result column index. */ + sort?: number; + /** @description Sort direction: desc (case insensitive) or asc (default). */ + dir?: string; + }; + header?: never; + path: { + /** @description Execution UUID; case insensitive. */ + uuid: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchRowsV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchCancelExecution: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Execution UUID; case insensitive. */ + uuid: string; + }; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": components["schemas"]["SqlWorkbenchEmptyRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchCancelledV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchGetHistory: { + parameters: { + query?: { + /** @description Page size; nonpositive or absent uses the default. Rows cap at maxPageSize; history caps at 200 (default 50). */ + limit?: number; + /** @description Configured target backend name. */ + backendName?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchHistoryV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchListNotebooks: { + parameters: { + query?: { + /** @description mine (default) or shared notebook library. */ + scope?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchNotebooksV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchCreateNotebook: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": components["schemas"]["SqlWorkbenchNotebookRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchNotebookV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchGetNotebook: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Notebook identifier. */ + id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchNotebookV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchUpdateNotebook: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Notebook identifier. */ + id: number; + }; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": components["schemas"]["SqlWorkbenchNotebookRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchNotebookV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchDeleteNotebook: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Notebook identifier. */ + id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchDeletedV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchPublishNotebook: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Notebook identifier. */ + id: number; + }; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": components["schemas"]["SqlWorkbenchPublishRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchNotebookV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchDuplicateNotebook: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Notebook identifier. */ + id: number; + }; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": components["schemas"]["SqlWorkbenchEmptyRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchNotebookV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchListVersions: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Notebook identifier. */ + id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchVersionsV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchGetVersion: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Notebook identifier. */ + id: number; + /** @description Notebook version number. */ + n: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchVersionV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchRestoreVersion: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Notebook identifier. */ + id: number; + /** @description Notebook version number. */ + n: number; + }; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": components["schemas"]["SqlWorkbenchEmptyRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchNotebookV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchListSnapshots: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Notebook identifier. */ + id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchSnapshotsV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchCreateSnapshot: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Notebook identifier. */ + id: number; + }; + cookie?: never; + }; + requestBody?: { + content: { + "application/json": components["schemas"]["SqlWorkbenchSnapshotRequestV1"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchSnapshotV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchDeleteSnapshot: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Notebook identifier. */ + id: number; + /** @description Snapshot identifier. */ + snapshotId: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchDeletedV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; + sqlWorkbenchExportResult: { + parameters: { + query?: { + /** @description csv (default), json or xlsx; case insensitive. */ + format?: string; + }; + header?: never; + path: { + /** @description Execution UUID; case insensitive. */ + uuid: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Attachment named sql-result-{short UUID}.{format}; Cache-Control: no-store */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SqlWorkbenchExportJsonV1"]; + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": components["schemas"]["SqlWorkbenchExportFileV1"]; + "text/csv; charset=utf-8": components["schemas"]["SqlWorkbenchExportFileV1"]; + }; + }; + /** @description Invalid input or execution limit exceeded */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Sign in required */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Permission denied */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Missing or invisible resource */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Execution UUID already used */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + /** @description Too many requests (code RATE_LIMITED); retry later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BasicErrorResponseV1"]; + }; + }; + }; + }; } diff --git a/scripts/gen-operations.mjs b/scripts/gen-operations.mjs index e3ccfcd..baa3fa9 100644 --- a/scripts/gen-operations.mjs +++ b/scripts/gen-operations.mjs @@ -16,6 +16,19 @@ import { dirname } from 'node:path' const [specPath = 'packages/ui-api-client/openapi/qqq-v1.json', outPath = 'packages/core/src/api/operations.ts'] = process.argv.slice(2) const spec = JSON.parse(readFileSync(specPath, 'utf8')) +const extensions = spec.info['x-qqq-extensions'] ?? [] +const extensionByOperation = new Map() +for (const e of extensions) for (const id of e.operations ?? []) extensionByOperation.set(id, e.name) +const ESTABLISHED_PREFIXES = { esb: 'esb', alerts: 'alerts', assistant: 'assistant', 'sql-workbench': 'sql-workbench', health: 'health' } + +/** The extension an operation belongs to: x-qqq-extensions, else its /qbit/{name} or established path prefix. */ +function extensionOf(id, path) { + if (extensionByOperation.has(id)) return extensionByOperation.get(id) + const rest = path.replace(/^\/qqq\/v1/, '').split('/') + if (rest[1] === 'qbit' && rest[2]) return rest[2] + return ESTABLISHED_PREFIXES[rest[1]] +} + const operations = [] for (const [path, item] of Object.entries(spec.paths)) { for (const method of ['get', 'post', 'put', 'patch', 'delete']) { @@ -31,6 +44,7 @@ for (const [path, item] of Object.entries(spec.paths)) { pathParams: params.filter((p) => p.in === 'path').map((p) => p.name), queryParams: params.filter((p) => p.in === 'query').map((p) => p.name), bodyTypes: Object.keys(op.requestBody?.content ?? {}), + ...(extensionOf(op.operationId, path) ? { extension: extensionOf(op.operationId, path) } : {}), }) } } @@ -41,7 +55,7 @@ const lines = [ ' * Licensed under the Apache License, Version 2.0 (see LICENSE).', ' */', '', - `// Generated by scripts/gen-operations.mjs from the UI API ${spec.info.version} document. Do not edit.`, + `// Generated by scripts/gen-operations.mjs from the UI API ${spec.info.version} document (core and ${extensions.length} extensions). Do not edit.`, '', 'export interface OperationInfo {', ' id: string', @@ -52,10 +66,25 @@ const lines = [ ' pathParams: string[]', ' queryParams: string[]', ' bodyTypes: string[]', + ' /** The extension (qbit or module) that serves this operation; absent for core operations. */', + ' extension?: string', + '}', + '', + '/** An extension document merged into the client document (info.x-qqq-extensions). */', + 'export interface DocumentExtension {', + ' name: string', + ' version: string', + ' pathPrefix?: string', + ' description?: string', '}', '', `export const UI_API_DOCUMENT_VERSION = ${JSON.stringify(spec.info.version)}`, '', + '/** The extensions merged into the client document, with the versions it was generated from. */', + 'export const DOCUMENT_EXTENSIONS: DocumentExtension[] = [', + ...extensions.map((e) => ` ${JSON.stringify({ name: e.name, version: e.version, pathPrefix: e.pathPrefix, description: (e.description ?? '').split('\n')[0].slice(0, 160) })},`), + ']', + '', 'export const OPERATIONS: OperationInfo[] = [', ...operations.map((o) => ` ${JSON.stringify(o)},`), ']', diff --git a/scripts/merge-extensions.mjs b/scripts/merge-extensions.mjs new file mode 100644 index 0000000..1e2d576 --- /dev/null +++ b/scripts/merge-extensions.mjs @@ -0,0 +1,91 @@ +#!/usr/bin/env node +/* + * Copyright 2026 QRun.IO, Inc. + * Licensed under the Apache License, Version 2.0 (see LICENSE). + */ + +/** + * Builds the client document from a core document plus every extension document found in the + * sibling checkouts of the QRun-IO workspace, and records where each came from. + * + * Usage: node scripts/merge-extensions.mjs [--core ] [--root ] [--out ] + * + * --core the core document; default the sample server's http://localhost:8077/qqq/v1/openapi.json + * (a server's document is already merged with the extensions that server has; those are + * checked for equality and recorded, not duplicated) + * --root the directory holding the qbit checkouts (default: QRUN_IO_ROOT, else the nearest + * ancestor of this repository that contains qbit-* directories) + * --out default packages/ui-api-client/openapi/qqq-v1.json + * + * Writes packages/ui-api-client/openapi/extension-sources.json: each extension's name, version, + * document path and the git branch and commit it was read at. + */ + +import { execFileSync } from 'node:child_process' +import { existsSync, readFileSync, readdirSync, writeFileSync } from 'node:fs' +import { dirname, join, relative, resolve } from 'node:path' +import { fileURLToPath } from 'node:url' +import { parse } from 'yaml' + +const repo = resolve(dirname(fileURLToPath(import.meta.url)), '..') +const args = process.argv.slice(2) +const option = (name, fallback) => { + const i = args.indexOf(name) + return i >= 0 ? args[i + 1] : fallback +} +const core = option('--core', 'http://localhost:8077/qqq/v1/openapi.json') +const out = option('--out', join(repo, 'packages/ui-api-client/openapi/qqq-v1.json')) + +function findRoot() { + if (process.env.QRUN_IO_ROOT) return process.env.QRUN_IO_ROOT + for (let dir = dirname(repo); dir !== dirname(dir); dir = dirname(dir)) { + if (readdirSync(dir).some((d) => d.startsWith('qbit-'))) return dir + } + throw new Error('No qbit-* checkouts found above this repository; pass --root or set QRUN_IO_ROOT.') +} +const root = option('--root', findRoot()) + +/** Where each repository keeps its extension documents (a qbit's own repo, or qqq for esb and health). */ +function candidates() { + const found = [] + const qqq = [join(root, '.worktrees/qqq-develop'), join(root, 'qqq')].find((d) => existsSync(join(d, 'qqq-esb'))) + if (qqq) { + for (const module of ['qqq-esb', 'qqq-middleware-javalin']) { + const dir = join(qqq, module, 'src/main/resources/openapi/qqq-v1') + if (existsSync(dir)) for (const f of readdirSync(dir)) if (f.endsWith('.yaml')) found.push(join(dir, f)) + } + } + for (const entry of readdirSync(root).filter((d) => d.startsWith('qbit-')).sort()) { + for (const base of [join(root, entry), join(root, entry, entry)]) { + const dir = join(base, 'src/main/resources/openapi/qqq-v1') + if (existsSync(dir)) for (const f of readdirSync(dir)) if (f.endsWith('.yaml')) found.push(join(dir, f)) + } + } + return found +} + +function git(dir, ...gitArgs) { + try { + return execFileSync('git', ['-C', dir, ...gitArgs], { encoding: 'utf8' }).trim() + } catch { + return '' + } +} + +const documents = candidates() +if (!documents.length) throw new Error(`No extension documents under ${root}`) +execFileSync('node', [join(repo, 'scripts/merge-spec.mjs'), '--out', out, core, ...documents], { stdio: 'inherit' }) + +const sources = documents.map((file) => { + const info = parse(readFileSync(file, 'utf8')).info ?? {} + const dir = dirname(file) + return { + name: String(info.title ?? '').replace(/^QQQ Middleware API extension: /, ''), + version: info.version, + document: relative(root, file), + branch: git(dir, 'rev-parse', '--abbrev-ref', 'HEAD'), + commit: git(dir, 'rev-parse', '--short', 'HEAD'), + } +}) +writeFileSync(join(dirname(out), 'extension-sources.json'), JSON.stringify({ core, extensions: sources }, null, 2) + '\n') +for (const s of sources) console.log(`${s.name.padEnd(16)} ${String(s.version).padEnd(7)} ${s.branch}@${s.commit} ${s.document}`) diff --git a/scripts/merge-spec.mjs b/scripts/merge-spec.mjs index bf0f8d3..da3f8e8 100644 --- a/scripts/merge-spec.mjs +++ b/scripts/merge-spec.mjs @@ -16,7 +16,11 @@ * Rules: paths and operations are unioned (a duplicate method on one path is an error); component * schemas are unioned (a name defined twice must be identical, e.g. BasicErrorResponseV1); the * core document's info, servers and securitySchemes are kept; tags are unioned; every extension's - * name and version is recorded in info.x-qqq-extensions. + * name, version, path prefix and operationIds are recorded in info.x-qqq-extensions. + * + * An extension whose operations the core input already carries (a server's merged document, e.g. + * the sample server's esb) is accepted when each such operation is identical; it is then recorded + * in info.x-qqq-extensions like any other. */ import { readFile, writeFile } from 'node:fs/promises' @@ -50,6 +54,14 @@ function deriveOperationId(method, path) { return id } +/** The path prefix an extension's operations share, relative to /qqq/v1 (`/qbit/{name}` or an established one such as `/esb`). */ +function pathPrefixOf(name, paths) { + const qbit = `/qqq/v1/qbit/${name}` + if (paths.length && paths.every((p) => p === qbit || p.startsWith(qbit + '/'))) return `/qbit/${name}` + const first = new Set(paths.map((p) => p.replace(/^\/qqq\/v1/, '').split('/')[1])) + return first.size === 1 ? `/${[...first][0]}` : undefined +} + async function load(source) { const text = /^https?:\/\//.test(source) ? await (await fetch(source)).text() : await readFile(source, 'utf8') return source.endsWith('.json') ? JSON.parse(text) : parse(text) @@ -72,12 +84,22 @@ const extensions = [] for (const source of extensionSources) { const doc = await load(source) const name = (doc.info?.title ?? '').replace(/^QQQ Middleware API extension: /, '') || source - extensions.push({ name, version: doc.info?.version, description: doc.info?.description }) + const operationIdsOfExtension = [] + const paths = Object.keys(doc.paths ?? {}) + extensions.push({ name, version: doc.info?.version, description: doc.info?.description, pathPrefix: pathPrefixOf(name, paths), operations: operationIdsOfExtension }) for (const [path, operations] of Object.entries(doc.paths ?? {})) { const target = (merged.paths[path] ??= {}) for (const [method, operation] of Object.entries(operations)) { - if (target[method]) throw new Error(`duplicate operation ${method.toUpperCase()} ${path} (from ${name})`) + if (!['get', 'put', 'post', 'patch', 'delete', 'head', 'options'].includes(method)) { + target[method] ??= operation // path-level parameters, summary + continue + } + if (operation.operationId) operationIdsOfExtension.push(operation.operationId) + if (target[method]) { + if (JSON.stringify(stable(target[method])) === JSON.stringify(stable(operation))) continue + throw new Error(`duplicate operation ${method.toUpperCase()} ${path} (from ${name})`) + } target[method] = operation } } diff --git a/scripts/parity-matrix.py b/scripts/parity-matrix.py index ca18f30..eca20f4 100644 --- a/scripts/parity-matrix.py +++ b/scripts/parity-matrix.py @@ -64,7 +64,7 @@ STATUS = { 'REC-024': (P, 'maxLength checked locally'), 'REC-025': (P, 'behaviors'), 'REC-026': (P, 'ranges checked locally'), 'REC-027': (P, 'server message'), 'REC-028': (P, 'record links name table and key, --follow opens them; URL links show the URL'), 'REC-029': (N, 'chip as [value]; colors and icons not shown (unit-tested; none in the sample)'), 'REC-030': (X, ''), 'REC-031': (N, 'raw code on view; no code editor (unit-tested)'), 'REC-032': (N, 'HTML shown as text (unit-tested)'), 'REC-033': (N, 'masked until --reveal; no copy (unit-tested; none in the sample)'), 'REC-034': (N, 'name plus qqq table download via the field route (unit-tested); live only for BLOB values, server finding 16'), 'REC-035': (N, 'create/update --upload field=path as multipart, replace and remove verified on a BLOB; FILE_UPLOAD formats not in the sample'), 'REC-036': (N, 'tooltip text in parentheses after the value (unit-tested)'), 'REC-037': (N, 'value rendered through the widget render model as text (unit-tested)'), 'REC-038': (N, 'value marked with ! (unit-tested)'), 'REC-039': (N, 'table get --help-content: view-screen roles, HTML/MARKDOWN as text (unit-tested; the sample has no help); qqq help show lists help alone'), 'REC-040': (N, 'section help with --help-content (unit-tested)'), 'REC-041': (N, 'table helpContent and helpContents slots with --help-content (unit-tested)'), 'REC-042': (N, 'qqq audit list [--asc]: entries newest first with field changes; the sample audits no table, verified with node tests and a local stub server'), 'REC-043': (N, 'without the audit process the audit table is queried with its auditTable and auditDetail joins (node tests)'), 'REC-044': (P, 'recordLabel'), 'REC-045': (P, 'labels resolved, defaults looked up'), 'REC-046': (P, 'server'), 'REC-047': (X, ''), 'REC-048': (P, 'fieldErrors by field'), 'REC-049': (X, ''), 'REC-050': (P, ''), 'REC-051': (P, ''), 'REC-052': (P, 'contingent fields'), - 'REC-053': (T, 'developer view'), 'REC-054': (T, ''), 'REC-055': (X, ''), 'REC-056': (X, ''), 'REC-057': (X, ''), 'REC-058': (X, ''), 'REC-059': (X, ''), 'REC-060': (T, 'adjusters wired, no sample to test'), 'REC-061': (T, ''), 'REC-062': (P, 'inline enums'), 'REC-063': (N, 'get, copy and update -i read with --variant; v1 writes ignore it (server finding #18)'), 'REC-064': (N, 'table get --join adds joined fields (queryJoins); verified with an association join'), 'REC-065': (P, 'an unchanged wall-clock time keeps the original instant and its precision'), + 'REC-053': (T, 'developer view'), 'REC-054': (T, ''), 'REC-055': (X, ''), 'REC-056': (X, ''), 'REC-057': (X, ''), 'REC-058': (X, ''), 'REC-059': (X, ''), 'REC-060': (T, 'adjusters wired, no sample to test'), 'REC-061': (T, ''), 'REC-062': (P, 'inline enums'), 'REC-063': (N, 'get, copy and update -i read with --variant; v1 writes ignore it (server finding #19)'), 'REC-064': (N, 'table get --join adds joined fields (queryJoins); verified with an association join'), 'REC-065': (P, 'an unchanged wall-clock time keeps the original instant and its precision'), # SEC 'SEC-001': (P, ''), 'SEC-002': (T, 'disabled tables listed with a reason'), 'SEC-003': (P, ''), 'SEC-004': (P, ''), 'SEC-005': (P, ''), 'SEC-006': (T, 'copy'), 'SEC-007': (P, ''), 'SEC-008': (T, ''), 'SEC-009': (P, 'widget get shows the refusal'), 'SEC-010': (P, ''), 'SEC-011': (T, 'saved views and reports'), 'SEC-012': (P, 'server'), 'SEC-013': (P, 'server'), 'SEC-014': (P, ''), 'SEC-015': (P, ''), 'SEC-020': (P, 'qqq login on a MOCK server'), 'SEC-021': (P, 'qqq logout calls POST /logout'), 'SEC-022': (P, 'exit 3 with the sign-in hint'),