flowbase-cli 0.1.18__tar.gz → 0.1.20__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/PKG-INFO +75 -2
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/README.md +74 -1
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/pyproject.toml +1 -1
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/src/flowbase_cli/__init__.py +1 -1
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/src/flowbase_cli/endpoints.py +61 -1
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/src/flowbase_cli/guide.py +2 -0
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/src/flowbase_cli/main.py +49 -0
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/src/flowbase_cli.egg-info/PKG-INFO +75 -2
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/tests/test_cli.py +1 -1
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/setup.cfg +0 -0
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/src/flowbase_cli.egg-info/SOURCES.txt +0 -0
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/src/flowbase_cli.egg-info/dependency_links.txt +0 -0
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/src/flowbase_cli.egg-info/entry_points.txt +0 -0
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/src/flowbase_cli.egg-info/top_level.txt +0 -0
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/tests/test_autonomy.py +0 -0
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/tests/test_iframes.py +0 -0
- {flowbase_cli-0.1.18 → flowbase_cli-0.1.20}/tests/test_recent_commands.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flowbase-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.20
|
|
4
4
|
Summary: Command line client for the FlowBase OpenAPI
|
|
5
5
|
Author: DeepFlowAI
|
|
6
6
|
License: Apache-2.0
|
|
@@ -324,7 +324,80 @@ Transport requests time out after 60 seconds. A lost write response has an unkno
|
|
|
324
324
|
- `flowbase docs catalogs formula-authoring`: formula/rollup sources, validation, saved-record trials and runtime draft preview. Supports reuse of calculated results through single relations and multi-level rollups (up to 10 dependency levels). Validation returns `dependencyGraph`, or `valid=false` with `code`/`errorPath` for invalid dependencies. Pass `fieldId` when validating an existing field. Derived values are read-only.
|
|
325
325
|
- `flowbase docs catalogs workflow-python`: record creation examples and failed-task retry. `workflows python-runtime OBJECT new` discovers current object bindings; `workflows executions` includes Python attempts, logs and `canRetry`.
|
|
326
326
|
|
|
327
|
-
Use `records list OBJECT --view-id VIEW --view-layout` for tree/Gantt projections; the default remains a flat list. `records update` accepts `updatedAt` and `planViewId` in its JSON body for version-checked plan edits. Formula validation
|
|
327
|
+
Use `records list OBJECT --view-id VIEW --view-layout` for tree/Gantt projections; the default remains a flat list. `records update` accepts `updatedAt` and `planViewId` in its JSON body for version-checked plan edits. Formula validation and custom-sample trials require metadata read; saved-record trials also require record read; workflow retry requires both metadata write and record write and explicit CLI confirmation (`--yes` in automation).
|
|
328
|
+
|
|
329
|
+
### Single-select formulas (4.21)
|
|
330
|
+
|
|
331
|
+
Use `flowbase formulas sources OBJECT` to discover local and one-hop single-select paths and their `options` (`id`, `label`, `lifecycle`). Use the returned stable option ID in `is_option(path, "OPTION_ID")`; `option_label(path)` reads the current label. Inactive options can model historical values. Raw single-select values cannot be compared with strings or returned directly.
|
|
332
|
+
|
|
333
|
+
Save a request such as this as `formula.json`, replacing the path and option ID with the source discovery response:
|
|
334
|
+
|
|
335
|
+
```json
|
|
336
|
+
{
|
|
337
|
+
"constraints": {"expression": "is_option(direction, \"OPTION_ID\")", "resultType": "boolean"},
|
|
338
|
+
"samples": {"direction": "OPTION_ID"},
|
|
339
|
+
"trial": true
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Run `flowbase formulas validate OBJECT --json-file formula.json`. For label output, use `option_label(direction)` with `resultType: "text.singleLine"`. Samples are stable option IDs or `null`; use `recordId` instead to test an accessible saved record. Inspect `valid`, `optionReferences` and `trial.status`: HTTP success alone does not mean the formula or trial succeeded. Save valid configuration through the existing `fields create` / `fields update` commands (metadata write permission).
|
|
344
|
+
|
|
345
|
+
These commands require a backend with 4.21 support. Existing CLI installations that already provide `formulas sources` and `formulas validate` can send the new expressions; updated offline help requires the updated CLI package. Employee CLI consumers continue reading calculated values and states through record commands.
|
|
346
|
+
|
|
347
|
+
### Conditional query rollups (4.23)
|
|
348
|
+
|
|
349
|
+
Read `flowbase docs catalogs conditional-rollup`, then discover stable IDs with `flowbase formulas collections OBJECT`. A query source uses `mode: "query"`, `objectId`, and 1–50 `conditions` of `{fieldId, operator, currentFieldId}`. All matching conditions must hold; optional fixed `filters` with `match: "all" | "any"` further narrow the matched records. No relation field is required. The catalog includes both standalone rollup and formula collection examples.
|
|
350
|
+
|
|
351
|
+
Submit the example with `flowbase formulas validate OBJECT --json-file query.json`. Include `fieldId` when editing an existing field. For a trial, use `trial: true` and a saved `recordId`; custom samples cannot trial collections. Validation requires metadata read; saved-record trials additionally require record read. Check `valid` and `trial.status`, then save valid constraints with `fields create/update`.
|
|
352
|
+
|
|
353
|
+
Matching uses saved current-record values. Empty matching inputs return `pending/matching_empty`; new records return `saved_required`. Successful authorized trials include collection parameters and candidate/matched counts. Full candidate permissions are checked before fixed filters; restricted results expose no totals or counts. Limits and timeouts never produce partial totals. See the catalog for compatible types, operators and budgets.
|
|
354
|
+
|
|
355
|
+
### Detail Page value assignments (4.22)
|
|
356
|
+
|
|
357
|
+
`flowbase docs catalogs page-value-rules` describes authoring and the edit sequence. Page snapshots support `setFieldValue` and `setDefaultFieldValue`; sources can traverse up to five single-record relations. `pages evaluate` continues to preview field states and component visibility only.
|
|
358
|
+
|
|
359
|
+
Create and detail Page actions accept an optional explicit `conversion`: `mapOptions` with `mappings: [{sourceOptionId, targetOptionId}]`, `copyOptions` for the same multiple-select definition through a relation, `truncateDate` for lower date precision, or `extractDate` for datetime → date in Asia/Shanghai. Read the catalog for the complete contract. Mappings use stable identities, never option names. Partial mappings warn; an unmapped runtime value fails the entire action. Disabled rules may retain inactive targets but must retain valid identities. Ordinary record writes remain strict and do not implicitly execute these conversions.
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
flowbase records get OBJECT RECORD
|
|
363
|
+
flowbase records page-value-context OBJECT RECORD
|
|
364
|
+
flowbase docs example records.page-value-event --output event.json
|
|
365
|
+
# Fill event.json with the returned pageId/revision, current edit delta,
|
|
366
|
+
# changed field IDs, and the preceding event's sources (initially {}).
|
|
367
|
+
flowbase records page-value-event OBJECT RECORD --json-file event.json
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
Context and event calls require both record read and write scopes, and do not save edits. Inspect `errors`, apply returned `values` to your edit delta, and carry `sources` into the next event's `previousSources`. Values use field keys, changed fields use IDs, and decimal assignments are returned as lossless strings. Defaults skip nonempty targets. Source/condition changes trigger assignment; simply reading or saving does not.
|
|
371
|
+
|
|
372
|
+
Save the merged edit delta with `records update`, including `pageId`, `valueRuleRevision` (the context's `revision`), and `updatedAt`. Configuration changes or stale record versions reject the save; reload and reconcile on 409. Page rules and field permissions are rechecked without rerunning assignments. Whole-record edits use the existing `bundle-save` / `configVersion` contract. Production context uses published configuration, while test Hosts use effective configuration.
|
|
373
|
+
|
|
374
|
+
### Official app store (4.14)
|
|
375
|
+
|
|
376
|
+
Read `flowbase docs catalogs app-store`. Reads and checks require metadata read; install, publish and listing changes require metadata write and confirmation (`--yes` in automation).
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
flowbase app-store context
|
|
380
|
+
flowbase app-store list --query tasks --page 1
|
|
381
|
+
flowbase app-store get PACKAGE
|
|
382
|
+
flowbase docs example app-store.install-check --output installation.json
|
|
383
|
+
# Set the reviewed version and desired app name.
|
|
384
|
+
flowbase app-store install-check PACKAGE --json-file installation.json
|
|
385
|
+
# Copy version/name into install.json; add the returned check and a fresh UUID request_id.
|
|
386
|
+
flowbase app-store install PACKAGE --json-file install.json --yes
|
|
387
|
+
flowbase app-store installation REQUEST_UUID
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Installation requires a clean enabled environment and creates configuration drafts only. Review and release them separately. The check binds the current Host environment, source package, name, API key and authorization; it expires after 15 minutes. Changed inputs require another check. After a timeout, query the receipt before retrying; reuse a request ID only with the identical body. Inspect `status`/`error`, since HTTP success may report `processing` or `failed`. A failed attempt needs a new check and request ID.
|
|
391
|
+
|
|
392
|
+
For eligible official publishers on the production Host:
|
|
393
|
+
|
|
394
|
+
1. `app-store sources` discovers committed source apps; production drafts must be resolved first.
|
|
395
|
+
2. `app-store source-check --json '{"app_id":"APP"}'` returns a signed source snapshot.
|
|
396
|
+
3. `docs example app-store.publish-check --output publication.json` provides all required bilingual product fields. Fill them and the returned source, package ID and version, then run `app-store publish-check --json-file publication.json`.
|
|
397
|
+
4. Review product content and checked resources. Add `check`, a fresh UUID `request_id`, and `preview_confirmed: true`; run `app-store publish --json-file publish.json --yes`.
|
|
398
|
+
5. Query `app-store publication REQUEST_UUID` or `app-store publications`. Use `app-store listing PACKAGE --json '{"listed":false}' --yes` to withdraw, or `true` to relist.
|
|
399
|
+
|
|
400
|
+
Store request bodies use snake_case. `--yes` does not bypass publishing eligibility, production-only rules, portability validation or rechecks. These added commands need an updated CLI installation and a backend with the corresponding public routes; the package version is bumped separately during release.
|
|
328
401
|
|
|
329
402
|
### Reusable iframe configuration (4.11)
|
|
330
403
|
|
|
@@ -315,7 +315,80 @@ Transport requests time out after 60 seconds. A lost write response has an unkno
|
|
|
315
315
|
- `flowbase docs catalogs formula-authoring`: formula/rollup sources, validation, saved-record trials and runtime draft preview. Supports reuse of calculated results through single relations and multi-level rollups (up to 10 dependency levels). Validation returns `dependencyGraph`, or `valid=false` with `code`/`errorPath` for invalid dependencies. Pass `fieldId` when validating an existing field. Derived values are read-only.
|
|
316
316
|
- `flowbase docs catalogs workflow-python`: record creation examples and failed-task retry. `workflows python-runtime OBJECT new` discovers current object bindings; `workflows executions` includes Python attempts, logs and `canRetry`.
|
|
317
317
|
|
|
318
|
-
Use `records list OBJECT --view-id VIEW --view-layout` for tree/Gantt projections; the default remains a flat list. `records update` accepts `updatedAt` and `planViewId` in its JSON body for version-checked plan edits. Formula validation
|
|
318
|
+
Use `records list OBJECT --view-id VIEW --view-layout` for tree/Gantt projections; the default remains a flat list. `records update` accepts `updatedAt` and `planViewId` in its JSON body for version-checked plan edits. Formula validation and custom-sample trials require metadata read; saved-record trials also require record read; workflow retry requires both metadata write and record write and explicit CLI confirmation (`--yes` in automation).
|
|
319
|
+
|
|
320
|
+
### Single-select formulas (4.21)
|
|
321
|
+
|
|
322
|
+
Use `flowbase formulas sources OBJECT` to discover local and one-hop single-select paths and their `options` (`id`, `label`, `lifecycle`). Use the returned stable option ID in `is_option(path, "OPTION_ID")`; `option_label(path)` reads the current label. Inactive options can model historical values. Raw single-select values cannot be compared with strings or returned directly.
|
|
323
|
+
|
|
324
|
+
Save a request such as this as `formula.json`, replacing the path and option ID with the source discovery response:
|
|
325
|
+
|
|
326
|
+
```json
|
|
327
|
+
{
|
|
328
|
+
"constraints": {"expression": "is_option(direction, \"OPTION_ID\")", "resultType": "boolean"},
|
|
329
|
+
"samples": {"direction": "OPTION_ID"},
|
|
330
|
+
"trial": true
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Run `flowbase formulas validate OBJECT --json-file formula.json`. For label output, use `option_label(direction)` with `resultType: "text.singleLine"`. Samples are stable option IDs or `null`; use `recordId` instead to test an accessible saved record. Inspect `valid`, `optionReferences` and `trial.status`: HTTP success alone does not mean the formula or trial succeeded. Save valid configuration through the existing `fields create` / `fields update` commands (metadata write permission).
|
|
335
|
+
|
|
336
|
+
These commands require a backend with 4.21 support. Existing CLI installations that already provide `formulas sources` and `formulas validate` can send the new expressions; updated offline help requires the updated CLI package. Employee CLI consumers continue reading calculated values and states through record commands.
|
|
337
|
+
|
|
338
|
+
### Conditional query rollups (4.23)
|
|
339
|
+
|
|
340
|
+
Read `flowbase docs catalogs conditional-rollup`, then discover stable IDs with `flowbase formulas collections OBJECT`. A query source uses `mode: "query"`, `objectId`, and 1–50 `conditions` of `{fieldId, operator, currentFieldId}`. All matching conditions must hold; optional fixed `filters` with `match: "all" | "any"` further narrow the matched records. No relation field is required. The catalog includes both standalone rollup and formula collection examples.
|
|
341
|
+
|
|
342
|
+
Submit the example with `flowbase formulas validate OBJECT --json-file query.json`. Include `fieldId` when editing an existing field. For a trial, use `trial: true` and a saved `recordId`; custom samples cannot trial collections. Validation requires metadata read; saved-record trials additionally require record read. Check `valid` and `trial.status`, then save valid constraints with `fields create/update`.
|
|
343
|
+
|
|
344
|
+
Matching uses saved current-record values. Empty matching inputs return `pending/matching_empty`; new records return `saved_required`. Successful authorized trials include collection parameters and candidate/matched counts. Full candidate permissions are checked before fixed filters; restricted results expose no totals or counts. Limits and timeouts never produce partial totals. See the catalog for compatible types, operators and budgets.
|
|
345
|
+
|
|
346
|
+
### Detail Page value assignments (4.22)
|
|
347
|
+
|
|
348
|
+
`flowbase docs catalogs page-value-rules` describes authoring and the edit sequence. Page snapshots support `setFieldValue` and `setDefaultFieldValue`; sources can traverse up to five single-record relations. `pages evaluate` continues to preview field states and component visibility only.
|
|
349
|
+
|
|
350
|
+
Create and detail Page actions accept an optional explicit `conversion`: `mapOptions` with `mappings: [{sourceOptionId, targetOptionId}]`, `copyOptions` for the same multiple-select definition through a relation, `truncateDate` for lower date precision, or `extractDate` for datetime → date in Asia/Shanghai. Read the catalog for the complete contract. Mappings use stable identities, never option names. Partial mappings warn; an unmapped runtime value fails the entire action. Disabled rules may retain inactive targets but must retain valid identities. Ordinary record writes remain strict and do not implicitly execute these conversions.
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
flowbase records get OBJECT RECORD
|
|
354
|
+
flowbase records page-value-context OBJECT RECORD
|
|
355
|
+
flowbase docs example records.page-value-event --output event.json
|
|
356
|
+
# Fill event.json with the returned pageId/revision, current edit delta,
|
|
357
|
+
# changed field IDs, and the preceding event's sources (initially {}).
|
|
358
|
+
flowbase records page-value-event OBJECT RECORD --json-file event.json
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Context and event calls require both record read and write scopes, and do not save edits. Inspect `errors`, apply returned `values` to your edit delta, and carry `sources` into the next event's `previousSources`. Values use field keys, changed fields use IDs, and decimal assignments are returned as lossless strings. Defaults skip nonempty targets. Source/condition changes trigger assignment; simply reading or saving does not.
|
|
362
|
+
|
|
363
|
+
Save the merged edit delta with `records update`, including `pageId`, `valueRuleRevision` (the context's `revision`), and `updatedAt`. Configuration changes or stale record versions reject the save; reload and reconcile on 409. Page rules and field permissions are rechecked without rerunning assignments. Whole-record edits use the existing `bundle-save` / `configVersion` contract. Production context uses published configuration, while test Hosts use effective configuration.
|
|
364
|
+
|
|
365
|
+
### Official app store (4.14)
|
|
366
|
+
|
|
367
|
+
Read `flowbase docs catalogs app-store`. Reads and checks require metadata read; install, publish and listing changes require metadata write and confirmation (`--yes` in automation).
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
flowbase app-store context
|
|
371
|
+
flowbase app-store list --query tasks --page 1
|
|
372
|
+
flowbase app-store get PACKAGE
|
|
373
|
+
flowbase docs example app-store.install-check --output installation.json
|
|
374
|
+
# Set the reviewed version and desired app name.
|
|
375
|
+
flowbase app-store install-check PACKAGE --json-file installation.json
|
|
376
|
+
# Copy version/name into install.json; add the returned check and a fresh UUID request_id.
|
|
377
|
+
flowbase app-store install PACKAGE --json-file install.json --yes
|
|
378
|
+
flowbase app-store installation REQUEST_UUID
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
Installation requires a clean enabled environment and creates configuration drafts only. Review and release them separately. The check binds the current Host environment, source package, name, API key and authorization; it expires after 15 minutes. Changed inputs require another check. After a timeout, query the receipt before retrying; reuse a request ID only with the identical body. Inspect `status`/`error`, since HTTP success may report `processing` or `failed`. A failed attempt needs a new check and request ID.
|
|
382
|
+
|
|
383
|
+
For eligible official publishers on the production Host:
|
|
384
|
+
|
|
385
|
+
1. `app-store sources` discovers committed source apps; production drafts must be resolved first.
|
|
386
|
+
2. `app-store source-check --json '{"app_id":"APP"}'` returns a signed source snapshot.
|
|
387
|
+
3. `docs example app-store.publish-check --output publication.json` provides all required bilingual product fields. Fill them and the returned source, package ID and version, then run `app-store publish-check --json-file publication.json`.
|
|
388
|
+
4. Review product content and checked resources. Add `check`, a fresh UUID `request_id`, and `preview_confirmed: true`; run `app-store publish --json-file publish.json --yes`.
|
|
389
|
+
5. Query `app-store publication REQUEST_UUID` or `app-store publications`. Use `app-store listing PACKAGE --json '{"listed":false}' --yes` to withdraw, or `true` to relist.
|
|
390
|
+
|
|
391
|
+
Store request bodies use snake_case. `--yes` does not bypass publishing eligibility, production-only rules, portability validation or rechecks. These added commands need an updated CLI installation and a backend with the corresponding public routes; the package version is bumped separately during release.
|
|
319
392
|
|
|
320
393
|
### Reusable iframe configuration (4.11)
|
|
321
394
|
|
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
4
|
from dataclasses import dataclass
|
|
5
|
+
import json
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
_STORE_PUBLICATION = {
|
|
9
|
+
"package_id": "official_tasks", "version": "1.0.0", "source": "from-source-check",
|
|
10
|
+
"product": {"name": {"zh": "项目任务", "en": "Project tasks"}, "summary": {"zh": "管理项目任务", "en": "Manage project tasks"},
|
|
11
|
+
"features": {"zh": "任务跟踪", "en": "Task tracking"}, "notices": {"zh": "仅安装配置", "en": "Configuration only"},
|
|
12
|
+
"guide": {"zh": "安装后检查并发布配置", "en": "Review and release the installed draft"}, "category": "projects"},
|
|
13
|
+
}
|
|
5
14
|
|
|
6
15
|
|
|
7
16
|
@dataclass(frozen=True)
|
|
@@ -22,6 +31,21 @@ class Endpoint:
|
|
|
22
31
|
|
|
23
32
|
|
|
24
33
|
ENDPOINTS = (
|
|
34
|
+
Endpoint("app-store.list", "flowbase_app_store_list", "GET", "/app-store", "metadata:read", "Browse official apps in the current Host environment.", "flowbase app-store list --query tasks --page 1"),
|
|
35
|
+
Endpoint("app-store.context", "flowbase_app_store_context", "GET", "/app-store/context", "metadata:read", "Discover tenant publishing eligibility and environment.", "flowbase app-store context"),
|
|
36
|
+
Endpoint("app-store.sources", "flowbase_app_store_sources", "GET", "/app-store/sources", "metadata:read", "List committed source apps; official publishers in production only.", "flowbase app-store sources", environments=("production",)),
|
|
37
|
+
Endpoint("app-store.source-check", "flowbase_app_store_source_check", "POST", "/app-store/sources/check", "metadata:read", "Check and bind a committed source app before publication.", "flowbase app-store source-check --json-file source.json", environments=("production",), request_body='{"app_id":"app_xxx"}'),
|
|
38
|
+
Endpoint("app-store.publications", "flowbase_app_store_publications", "GET", "/app-store/published", "metadata:read", "List tenant publication history; production only.", "flowbase app-store publications", environments=("production",)),
|
|
39
|
+
Endpoint("app-store.publication", "flowbase_app_store_publication", "GET", "/app-store/published/{publication_id}", "metadata:read", "Read publication status after confirmation or timeout.", "flowbase app-store publication UUID", environments=("production",)),
|
|
40
|
+
Endpoint("app-store.publish-check", "flowbase_app_store_publish_check", "POST", "/app-store/published/check", "metadata:read", "Validate publication and return a short-lived check; official publishers only.", "flowbase app-store publish-check --json-file publication.json", environments=("production",), request_body=json.dumps(_STORE_PUBLICATION)),
|
|
41
|
+
Endpoint("app-store.publish", "flowbase_app_store_publish", "POST", "/app-store/published", "metadata:write", "Publish checked official app; requires reviewed product content and preview_confirmed=true. Inspect status.", "flowbase app-store publish --json-file publish.json --yes", True, environments=("production",), preflight_operation_id="flowbase_app_store_publish_check", request_body=json.dumps({**_STORE_PUBLICATION, "request_id": "00000000-0000-4000-8000-000000000001", "check": "from-publish-check", "preview_confirmed": True})),
|
|
42
|
+
Endpoint("app-store.listing", "flowbase_app_store_listing", "POST", "/app-store/published/{package_id}/listing", "metadata:write", "List or withdraw an official app; publisher eligibility is rechecked.", "flowbase app-store listing official_tasks --json-file listing.json --yes", True, environments=("production",), request_body='{"listed":false}'),
|
|
43
|
+
Endpoint("app-store.installation", "flowbase_app_store_installation", "GET", "/app-store/installations/{installation_id}", "metadata:read", "Read installation status in this Host environment.", "flowbase app-store installation UUID"),
|
|
44
|
+
Endpoint("app-store.get", "flowbase_app_store_get", "GET", "/app-store/{package_id}", "metadata:read", "Read app product details, resources and installation state.", "flowbase app-store get official_tasks --version 1.0.0"),
|
|
45
|
+
Endpoint("app-store.install-check", "flowbase_app_store_install_check", "POST", "/app-store/{package_id}/check", "metadata:read", "Check installation into a clean environment; returns check and resources without adding drafts.", "flowbase app-store install-check official_tasks --json-file installation.json", request_body='{"version":"1.0.0","name":"Tasks"}'),
|
|
46
|
+
Endpoint("app-store.install", "flowbase_app_store_install", "POST", "/app-store/{package_id}/install", "metadata:write", "Install a checked app as a configuration draft; does not release. Inspect status.", "flowbase app-store install official_tasks --json-file install.json --yes", True, preflight_operation_id="flowbase_app_store_install_check", request_body='{"version":"1.0.0","name":"Tasks","request_id":"00000000-0000-4000-8000-000000000001","check":"from-install-check"}'),
|
|
47
|
+
Endpoint("records.page-value-context", "flowbase_records_page_value_context", "GET", "/objects/{object_id}/records/{record_id}/page-value-context", "records:write", "Load effective detail pageId, revision and updatedAt before assignment events; also requires records:read. No writes.", "flowbase records page-value-context obj_xxx rec_xxx"),
|
|
48
|
+
Endpoint("records.page-value-event", "flowbase_records_page_value_event", "POST", "/objects/{object_id}/records/{record_id}/page-value-event", "records:write", "Evaluate assignments against an edit delta; also requires records:read. Returns values/errors/sources; never saves.", "flowbase records page-value-event obj_xxx rec_xxx --json-file event.json", request_body='{"pageId":"pag_xxx","revision":"from-page-value-context","values":{"amount":12.50},"changedFieldIds":["fld_amount"],"previousSources":{}}'),
|
|
25
49
|
Endpoint("apps.navigation", "flowbase_apps_navigation", "POST", "/apps/{app_id}/navigation", "metadata:write", "Edit app sections and navigation positions; read apps get first. See app-sections catalog.", "flowbase apps navigation app_xxx --json-file navigation.json --yes", True, request_body='{"type":"appSection.create","name":"Sales"}'),
|
|
26
50
|
Endpoint("dashboards.record-view-options", "flowbase_dashboards_record_view_options", "GET", "/dashboards/record-view-options", "metadata:read", "Discover draft objects and fields for record-view components.", "flowbase dashboards record-view-options"),
|
|
27
51
|
Endpoint("dashboards.record-view-preview", "flowbase_dashboards_record_view_preview", "POST", "/dashboards/{dashboard_id}/record-view-preview", "metadata:read", "Preview an unsaved record-view component; also requires records:read. No writes; current Host data and draft config.", "flowbase dashboards record-view-preview dsh_xxx --json-file preview.json", request_body='{"component":{"type":"record_view","title":"Orders","layout":{"x":0,"y":0,"w":6,"h":10},"recordView":{"objectId":"obj_xxx","match":"all","filters":[],"fieldIds":["fld_xxx"],"pageSize":10,"showSearch":true,"followFilters":true}},"filters":[],"filterValues":{},"page":1,"q":""}'),
|
|
@@ -64,7 +88,7 @@ ENDPOINTS = (
|
|
|
64
88
|
|
|
65
89
|
Endpoint('formulas.sources', 'flowbase_formulas_sources', 'GET', '/objects/{object_id}/formula/sources', 'metadata:read', 'Discover scalar formula sources in the draft.', 'flowbase formulas sources obj_xxx'),
|
|
66
90
|
Endpoint('formulas.collections', 'flowbase_formulas_collections', 'GET', '/objects/{object_id}/formula/collections', 'metadata:read', 'Discover collection object and field IDs in the draft.', 'flowbase formulas collections obj_xxx'),
|
|
67
|
-
Endpoint('formulas.validate', 'flowbase_formulas_validate', 'POST', '/objects/{object_id}/formula/validate', 'metadata:read', 'Validate formula or rollup;
|
|
91
|
+
Endpoint('formulas.validate', 'flowbase_formulas_validate', 'POST', '/objects/{object_id}/formula/validate', 'metadata:read', 'Validate formula or rollup; custom samples need metadata:read only, saved-record trials also require records:read. No writes.', 'flowbase formulas validate obj_xxx --json-file formula.json', request_body='{"constraints":{"expression":"amount * 2","resultType":"number","scale":2},"samples":{"amount":12.50},"trial":true}'),
|
|
68
92
|
Endpoint('records.formula-preview', 'flowbase_records_formula_preview', 'POST', '/objects/{object_id}/formula-preview', 'records:read', 'Preview runtime formulas without saving. New rollups remain pending; saved rollups use saved data.', 'flowbase records formula-preview obj_xxx --json-file preview.json', request_body='{"values":{"amount":12.50}}'),
|
|
69
93
|
Endpoint('records.bundle-init', 'flowbase_records_bundle_init', 'GET', '/objects/{object_id}/bundle/init', 'records:read', 'Load configuration and collection versions before an atomic write.', 'flowbase records bundle-init obj_xxx --record-id rec_xxx'),
|
|
70
94
|
Endpoint('records.bundle-save', 'flowbase_records_bundle_save', 'POST', '/objects/{object_id}/bundle', 'records:write', 'Atomically save parent and configured related rows. Reuse submissionId only for identical retries.', 'flowbase records bundle-save obj_xxx --json-file bundle.json', request_body='{"submissionId":"unique-submission-0001","configVersion":"from-bundle-init","values":{"name":"Order"},"components":[]}'),
|
|
@@ -1369,6 +1393,8 @@ PAGE_RULES = {
|
|
|
1369
1393
|
"lookup.department": ("eq", "neq", "in", "not_in", "is_empty", "is_not_empty"),
|
|
1370
1394
|
},
|
|
1371
1395
|
"actions": (
|
|
1396
|
+
{"type": "setDefaultFieldValue", "pageTypes": ("create", "detail"), "requiredKeys": ("type", "fieldId", "sourceFieldId", "sourcePath"), "optionalKeys": ("conversion",), "maxSourceHops": 5},
|
|
1397
|
+
{"type": "setFieldValue", "pageTypes": ("create", "detail"), "requiredKeys": ("type", "fieldId", "sourceFieldId", "sourcePath"), "optionalKeys": ("conversion",), "maxSourceHops": 5},
|
|
1372
1398
|
{
|
|
1373
1399
|
"type": "setFieldState",
|
|
1374
1400
|
"pageTypes": ("create", "detail"),
|
|
@@ -1601,6 +1627,38 @@ FORMS = {
|
|
|
1601
1627
|
}
|
|
1602
1628
|
|
|
1603
1629
|
CATALOGS = {
|
|
1630
|
+
"app-store": {
|
|
1631
|
+
"permissions": "Reads/checks require metadata:read; install/publish/listing require metadata:write and --yes in automation. API keys retain tenant publisher eligibility and Host environment restrictions. Check and confirm with the same key; authorization changes invalidate checks.",
|
|
1632
|
+
"install": ["app-store list [--query TEXT] [--category CATEGORY] [--page N]; pages contain up to 12 items, follow total.", "app-store get PACKAGE [--version VERSION]: review product, notices, guide, resources and domains.", "app-store install-check PACKAGE --json-file installation.json with version/name requires an enabled environment with no outstanding drafts.", "Copy the check into the same version/name body; add a fresh UUID request_id. app-store install PACKAGE --json-file install.json --yes adds a draft only.", "Inspect status, then app-store installation UUID. Review changes and use the existing release workflow separately."],
|
|
1633
|
+
"publish": ["Production only: app-store context reports canPublish. The tenant must be enabled for official publishing.", "app-store sources requires no production drafts. source-check with app_id returns a signed committed source.", "Use docs example app-store.publish-check; replace source, package_id, version and all bilingual product content. publish-check validates portability and returns check.", "Review product content and resources, add check, a fresh UUID request_id and preview_confirmed=true. app-store publish --json-file publish.json --yes.", "Inspect app-store publication UUID or publications. app-store listing PACKAGE with {listed:false} withdraws the package; true relists it, both require --yes."],
|
|
1634
|
+
"recovery": "Checks expire after 15 minutes; changed inputs/environment/catalog/permissions require a new check. Reuse request_id only for identical retries; request IDs are tenant-wide for publications and installation IDs are queried in their original Host environment. After a timeout query the receipt first. HTTP success can contain processing/failed: inspect status/error. Failed attempts need a fresh check and request_id. --yes never bypasses server checks.",
|
|
1635
|
+
"bodyNaming": "Store bodies use snake_case (app_id, package_id, request_id, preview_confirmed), exactly as docs example shows.",
|
|
1636
|
+
},
|
|
1637
|
+
"page-value-rules": {
|
|
1638
|
+
"authoring": "pages get/update preserves the full Page snapshot and baseRevision. Create and detail Pages support setFieldValue and setDefaultFieldValue; targets must be placed writable ordinary fields. sourcePath is empty for the current object or up to 5 single-relation hops. Enabled assignment chains are rejected. Create sources must be available before the record is saved.",
|
|
1639
|
+
"action": {"type": "setDefaultFieldValue", "fieldId": "fld_target", "sourceFieldId": "fld_source", "sourcePath": [{"relationFieldId": "fld_relation", "targetObjectId": "obj_source"}]},
|
|
1640
|
+
"conversions": {
|
|
1641
|
+
"mapOptions": {"type": "mapOptions", "mappings": [{"sourceOptionId": "opt_source", "targetOptionId": "opt_target"}]},
|
|
1642
|
+
"copyOptions": {"type": "copyOptions"},
|
|
1643
|
+
"truncateDate": {"type": "truncateDate"},
|
|
1644
|
+
"extractDate": {"type": "extractDate"},
|
|
1645
|
+
"rules": "Put an explicit conversion on the action. mapOptions supports ordinary single-to-single or multiple-to-multiple across field definitions, with at least one identity-owned mapping; partial mappings warn and fail at runtime when hit. Historical inactive sources are allowed; active rules cannot target inactive options. Disabled rules relax only target lifecycle. copyOptions supports the same multiple-select definition through a relation, never self-assignment. truncateDate only lowers day/month precision; extractDate converts datetime to Asia/Shanghai then extracts the target date precision. No implicit mapping, guessed names, text parsing or date padding. Missing conversion retains legacy semantics. Multiselect results deduplicate before maxSelections; one failure rejects the whole action.",
|
|
1646
|
+
},
|
|
1647
|
+
"steps": ["records get OBJECT RECORD reads saved values; records page-value-context OBJECT RECORD [--page-id PAGE] returns the effective pageId/revision/updatedAt. Production uses published configuration; test Hosts use their effective configuration.", "records page-value-event OBJECT RECORD --json-file event.json: copy pageId/revision; values is the full current edit delta keyed by field key, changedFieldIds contains IDs changed by this event, previousSources carries the last response sources.", "Inspect errors before applying response values to the edit delta. Empty-only defaults skip nonempty targets; assignments run on relevant source/condition changes, not automatically on read or save. Formula collections use saved data.", "Save the merged edit delta using records update with pageId, valueRuleRevision=revision and updatedAt from context. The server rechecks page/field constraints without rerunning assignments. For whole-record bundles use bundle-save and its configVersion."],
|
|
1648
|
+
"updateExample": {"values": {"source": "edited", "target": "assigned"}, "pageId": "pag_xxx", "valueRuleRevision": "from-context", "updatedAt": "from-context"},
|
|
1649
|
+
"permissions": "Context/event require records:read and records:write, retain static field visibility/writability and approval locks, and never persist values. Old records update calls without Page context retain their existing behavior.",
|
|
1650
|
+
"limits": "pages evaluate only previews field states/component visibility on draft samples; it does not evaluate value assignments. Event errors are keyed by target field ID; values use field keys and decimal assignments are lossless strings. On 409 reload context and reconcile edits.",
|
|
1651
|
+
},
|
|
1652
|
+
"conditional-rollup": {
|
|
1653
|
+
"discover": "formulas collections OBJECT returns source/current object and field IDs, types, constraints and calculation metadata. Use direct ordinary fields for conditions, never labels, field keys or calculated results.",
|
|
1654
|
+
"example": {"fieldType": "rollup", "constraints": {"source": {"mode": "query", "objectId": "obj_lines", "conditions": [{"fieldId": "fld_month", "operator": "eq", "currentFieldId": "fld_period"}], "fieldId": "fld_amount", "filters": [], "match": "all"}, "operation": "sum", "resultType": "number", "scale": 2}, "trial": True, "recordId": "rec_report"},
|
|
1655
|
+
"formulaExample": {"expression": "sum(lines)", "resultType": "number", "scale": 2, "languageVersion": 2, "collections": {"lines": {"mode": "query", "objectId": "obj_lines", "conditions": [{"fieldId": "fld_month", "operator": "eq", "currentFieldId": "fld_period"}], "fieldId": "fld_amount"}}},
|
|
1656
|
+
"conditions": "1-50 unique conditions, always AND. Each is {fieldId,operator,currentFieldId}: source field versus saved current-record field. No relationFieldId is needed. Optional fixed filters (0-50) with match=all/any further narrow candidates.",
|
|
1657
|
+
"types": "text.singleLine/autonumber, number/currency/percent, date/datetime, boolean, lookup.record and select.single. Numbers allow eq/neq/gt/gte/lt/lte; dates allow eq/neq/before/after; others eq/neq. Types must match except single-line text/autonumber interchange; date precision, currency and relation target must match. Single-select matching requires the exact same object/field definition. No calculated fields, arbitrary paths, current-user or current-time variables.",
|
|
1658
|
+
"validate": "formulas validate OBJECT --json-file query.json returns valid/dependencyGraph or code/errorPath. Include fieldId when editing. Save constraints via fields create/update. Trial requires a saved recordId and records:read in addition to metadata:read; samples alone cannot trial a collection.",
|
|
1659
|
+
"results": "Check valid and trial.status, not HTTP status alone. Authorized successful trials include collections parameters/candidateCount/matchedCount. Empty matching inputs yield pending/matching_empty; new records saved_required; limits/timeouts are errors, never partial totals. Empty authorized candidates yield normal aggregate empty/zero semantics.",
|
|
1660
|
+
"permissionsAndLimits": "All matching fields, fixed filters, result dependencies and the entire candidate record set must be readable before fixed filtering. Restricted trials expose no values/counts. At most 1000 candidates per collection and 20000 request dependency nodes; query timeout is server-configured (default 3 seconds). Saved changes affect the next read, not an unsaved preview or push update.",
|
|
1661
|
+
},
|
|
1604
1662
|
"app-sections": {
|
|
1605
1663
|
"read": "apps get APP returns sections and sectionId on groups/objects/dashboards/iframes. Null means unassigned; groups define their members' section.",
|
|
1606
1664
|
"write": "apps navigation APP --json-file navigation.json --yes writes one atomic draft operation and returns id/draftRevision. Read current locations first; stale moves fail without changes.",
|
|
@@ -1646,6 +1704,8 @@ CATALOGS = {
|
|
|
1646
1704
|
"rules": "Copy every visible component and its version. Update/delete rows also require recordId and updatedAt. Relation is injected by the server; omit it from row values. API-key receipts are isolated per key. Conflict: reload, reconcile and use a new submissionId. Max 200 resulting detail rows.",
|
|
1647
1705
|
},
|
|
1648
1706
|
"formula-authoring": {
|
|
1707
|
+
"conditionalQuery": "See docs catalogs conditional-rollup for mode=query matching against saved current-record fields, examples, permissions and trial states.",
|
|
1708
|
+
"singleSelect": "sources includes ordinary single-select fields with options (id, label, lifecycle). Use is_option(path, fixed_option_id), option_label(path), is_empty(path) or path is None. Identity literals must belong to that source; raw selects cannot be forwarded or converted to text. Inactive options remain valid for historical calculations. Samples contain option IDs or null. validate returns optionReferences with current labels and positions.",
|
|
1649
1709
|
"dependencies": "Single relations and collections can reuse formula/rollup results. Maximum dependency depth is 10; cycles are rejected. sources returns depth/dependencyIds; collections includes calculation metadata. validate returns dependencyGraph, or valid=false with code/errorPath. Pass fieldId when validating an existing field.",
|
|
1650
1710
|
"steps": ["formulas sources OBJECT discovers scalar paths; formulas collections OBJECT discovers stable object/field IDs.", "formulas validate OBJECT --json-file formula.json validates constraints; trial=true uses samples or a saved recordId.", "fields create/update saves metadata. records formula-preview previews runtime values without saving."],
|
|
1651
1711
|
"rollupExample": {"fieldType": "rollup", "constraints": {"source": {"mode": "reverse", "objectId": "obj_lines", "relationFieldId": "fld_order", "fieldId": "fld_amount"}, "operation": "sum", "resultType": "number", "scale": 2}, "trial": True, "recordId": "rec_order"},
|
|
@@ -20,6 +20,8 @@ GUIDE = {
|
|
|
20
20
|
],
|
|
21
21
|
"connection": {"host": "--host > FLOWBASE_HOST > http://flowbase.localhost:5001", "key": "--api-key > FLOWBASE_API_KEY;不把密钥写入请求文件或日志"},
|
|
22
22
|
"metadata": [
|
|
23
|
+
"应用商店使用 app-store 命令,先读 docs catalogs app-store;安装只生成草稿,发布商店版本受租户资格和正式 Host 限制,确认前必须检查。",
|
|
24
|
+
"条件查询汇总先读 docs catalogs conditional-rollup;页面赋值先读 page-value-rules,用 records page-value-context / page-value-event 取得上下文和赋值结果。",
|
|
23
25
|
"元数据写入产生草稿,不自动提交或发布。测试环境可用于验证草稿;正式记录 API 使用已发布配置。",
|
|
24
26
|
"changes commit 提交当前测试环境的全部草稿;changes release 发布测试版本;changes direct-release 在正式环境执行预检查和确认后发布全部正式草稿。",
|
|
25
27
|
"发布/环境重置影响整个环境,不能作为单个资源测试的常规清理步骤。",
|
|
@@ -927,6 +927,9 @@ def _print_direct_release_preflight(preflight: dict[str, Any]) -> None:
|
|
|
927
927
|
if isinstance(check, dict):
|
|
928
928
|
mark = "OK" if check.get("ok") else "FAIL"
|
|
929
929
|
print(f" [{mark}] {check.get('label', '')}", file=sys.stderr)
|
|
930
|
+
for warning in preflight.get("warnings", []):
|
|
931
|
+
if isinstance(warning, dict):
|
|
932
|
+
print(f" [WARN] {warning.get('message', '')}", file=sys.stderr)
|
|
930
933
|
print(f" RISK: {preflight.get('risk', 'This bypasses test environments.')}", file=sys.stderr)
|
|
931
934
|
|
|
932
935
|
|
|
@@ -997,8 +1000,25 @@ def handle_formulas(args: argparse.Namespace) -> int:
|
|
|
997
1000
|
return run_request(args, f"formulas.{args.formulas_action}", path_params={"object_id": args.object_id}, body=body)
|
|
998
1001
|
|
|
999
1002
|
|
|
1003
|
+
def handle_app_store(args: argparse.Namespace) -> int:
|
|
1004
|
+
action = args.app_store_action
|
|
1005
|
+
path = {key: getattr(args, key) for key in ("package_id", "publication_id", "installation_id") if hasattr(args, key)}
|
|
1006
|
+
query = None
|
|
1007
|
+
if action == "list":
|
|
1008
|
+
query = {"q": args.query, "category": args.category, "page": args.page}
|
|
1009
|
+
elif action == "get":
|
|
1010
|
+
query = {"version": args.version}
|
|
1011
|
+
body = load_json_payload(args.json, args.json_file) if hasattr(args, "json") else None
|
|
1012
|
+
return run_request(args, f"app-store.{action}", path_params=path, query=query, body=body)
|
|
1013
|
+
|
|
1014
|
+
|
|
1000
1015
|
def handle_records(args: argparse.Namespace) -> int:
|
|
1001
1016
|
action = args.records_action
|
|
1017
|
+
if action in ("page-value-context", "page-value-event"):
|
|
1018
|
+
path = {"object_id": args.object_id, "record_id": args.record_id}
|
|
1019
|
+
query = {"page_id": args.page_id} if action == "page-value-context" else None
|
|
1020
|
+
body = load_json_payload(args.json, args.json_file) if action == "page-value-event" else None
|
|
1021
|
+
return run_request(args, f"records.{action}", path_params=path, query=query, body=body)
|
|
1002
1022
|
if action in ("bundle-init", "bundle-status", "bundle-save", "formula-preview", "hierarchy-candidates", "gantt-candidates"):
|
|
1003
1023
|
path = {"object_id": args.object_id}
|
|
1004
1024
|
query = {}
|
|
@@ -1641,6 +1661,14 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
1641
1661
|
item.add_argument("--field", required=True, help="Stable field ID.")
|
|
1642
1662
|
item.add_argument("--exclude", required=action == "gantt-candidates", default="")
|
|
1643
1663
|
item.add_argument("--query", default="")
|
|
1664
|
+
for action in ("page-value-context", "page-value-event"):
|
|
1665
|
+
item = record_actions.add_parser(action)
|
|
1666
|
+
item.add_argument("object_id")
|
|
1667
|
+
item.add_argument("record_id")
|
|
1668
|
+
if action == "page-value-context":
|
|
1669
|
+
item.add_argument("--page-id", help="Effective detail Page; defaults to the object's detail Page.")
|
|
1670
|
+
else:
|
|
1671
|
+
add_json_args(item, endpoint_key=f"records.{action}")
|
|
1644
1672
|
records.set_defaults(handler=handle_records)
|
|
1645
1673
|
|
|
1646
1674
|
roles = groups.add_parser("roles", help="Manage organization roles (production Host only).")
|
|
@@ -1668,6 +1696,27 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
1668
1696
|
if action == "validate":
|
|
1669
1697
|
add_json_args(item, endpoint_key="formulas.validate")
|
|
1670
1698
|
formulas.set_defaults(handler=handle_formulas)
|
|
1699
|
+
app_store = groups.add_parser("app-store", help="Browse, install and publish official apps; see docs catalogs app-store.")
|
|
1700
|
+
store_actions = app_store.add_subparsers(dest="app_store_action", required=True)
|
|
1701
|
+
for action in ("list", "context", "sources", "source-check", "publications", "publication", "publish-check", "publish", "listing", "installation", "get", "install-check", "install"):
|
|
1702
|
+
item = store_actions.add_parser(action)
|
|
1703
|
+
if action in ("get", "install-check", "install", "listing"):
|
|
1704
|
+
item.add_argument("package_id")
|
|
1705
|
+
elif action == "publication":
|
|
1706
|
+
item.add_argument("publication_id")
|
|
1707
|
+
elif action == "installation":
|
|
1708
|
+
item.add_argument("installation_id")
|
|
1709
|
+
if action == "list":
|
|
1710
|
+
item.add_argument("--query", default="")
|
|
1711
|
+
item.add_argument("--category", default="", choices=("", "sales", "projects", "hr", "procurement", "other"))
|
|
1712
|
+
item.add_argument("--page", type=int, default=1)
|
|
1713
|
+
elif action == "get":
|
|
1714
|
+
item.add_argument("--version")
|
|
1715
|
+
if action in ("source-check", "publish-check", "publish", "listing", "install-check", "install"):
|
|
1716
|
+
add_json_args(item, endpoint_key=f"app-store.{action}")
|
|
1717
|
+
if action in ("publish", "listing", "install"):
|
|
1718
|
+
add_yes(item)
|
|
1719
|
+
app_store.set_defaults(handler=handle_app_store)
|
|
1671
1720
|
return parser
|
|
1672
1721
|
|
|
1673
1722
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flowbase-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.20
|
|
4
4
|
Summary: Command line client for the FlowBase OpenAPI
|
|
5
5
|
Author: DeepFlowAI
|
|
6
6
|
License: Apache-2.0
|
|
@@ -324,7 +324,80 @@ Transport requests time out after 60 seconds. A lost write response has an unkno
|
|
|
324
324
|
- `flowbase docs catalogs formula-authoring`: formula/rollup sources, validation, saved-record trials and runtime draft preview. Supports reuse of calculated results through single relations and multi-level rollups (up to 10 dependency levels). Validation returns `dependencyGraph`, or `valid=false` with `code`/`errorPath` for invalid dependencies. Pass `fieldId` when validating an existing field. Derived values are read-only.
|
|
325
325
|
- `flowbase docs catalogs workflow-python`: record creation examples and failed-task retry. `workflows python-runtime OBJECT new` discovers current object bindings; `workflows executions` includes Python attempts, logs and `canRetry`.
|
|
326
326
|
|
|
327
|
-
Use `records list OBJECT --view-id VIEW --view-layout` for tree/Gantt projections; the default remains a flat list. `records update` accepts `updatedAt` and `planViewId` in its JSON body for version-checked plan edits. Formula validation
|
|
327
|
+
Use `records list OBJECT --view-id VIEW --view-layout` for tree/Gantt projections; the default remains a flat list. `records update` accepts `updatedAt` and `planViewId` in its JSON body for version-checked plan edits. Formula validation and custom-sample trials require metadata read; saved-record trials also require record read; workflow retry requires both metadata write and record write and explicit CLI confirmation (`--yes` in automation).
|
|
328
|
+
|
|
329
|
+
### Single-select formulas (4.21)
|
|
330
|
+
|
|
331
|
+
Use `flowbase formulas sources OBJECT` to discover local and one-hop single-select paths and their `options` (`id`, `label`, `lifecycle`). Use the returned stable option ID in `is_option(path, "OPTION_ID")`; `option_label(path)` reads the current label. Inactive options can model historical values. Raw single-select values cannot be compared with strings or returned directly.
|
|
332
|
+
|
|
333
|
+
Save a request such as this as `formula.json`, replacing the path and option ID with the source discovery response:
|
|
334
|
+
|
|
335
|
+
```json
|
|
336
|
+
{
|
|
337
|
+
"constraints": {"expression": "is_option(direction, \"OPTION_ID\")", "resultType": "boolean"},
|
|
338
|
+
"samples": {"direction": "OPTION_ID"},
|
|
339
|
+
"trial": true
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Run `flowbase formulas validate OBJECT --json-file formula.json`. For label output, use `option_label(direction)` with `resultType: "text.singleLine"`. Samples are stable option IDs or `null`; use `recordId` instead to test an accessible saved record. Inspect `valid`, `optionReferences` and `trial.status`: HTTP success alone does not mean the formula or trial succeeded. Save valid configuration through the existing `fields create` / `fields update` commands (metadata write permission).
|
|
344
|
+
|
|
345
|
+
These commands require a backend with 4.21 support. Existing CLI installations that already provide `formulas sources` and `formulas validate` can send the new expressions; updated offline help requires the updated CLI package. Employee CLI consumers continue reading calculated values and states through record commands.
|
|
346
|
+
|
|
347
|
+
### Conditional query rollups (4.23)
|
|
348
|
+
|
|
349
|
+
Read `flowbase docs catalogs conditional-rollup`, then discover stable IDs with `flowbase formulas collections OBJECT`. A query source uses `mode: "query"`, `objectId`, and 1–50 `conditions` of `{fieldId, operator, currentFieldId}`. All matching conditions must hold; optional fixed `filters` with `match: "all" | "any"` further narrow the matched records. No relation field is required. The catalog includes both standalone rollup and formula collection examples.
|
|
350
|
+
|
|
351
|
+
Submit the example with `flowbase formulas validate OBJECT --json-file query.json`. Include `fieldId` when editing an existing field. For a trial, use `trial: true` and a saved `recordId`; custom samples cannot trial collections. Validation requires metadata read; saved-record trials additionally require record read. Check `valid` and `trial.status`, then save valid constraints with `fields create/update`.
|
|
352
|
+
|
|
353
|
+
Matching uses saved current-record values. Empty matching inputs return `pending/matching_empty`; new records return `saved_required`. Successful authorized trials include collection parameters and candidate/matched counts. Full candidate permissions are checked before fixed filters; restricted results expose no totals or counts. Limits and timeouts never produce partial totals. See the catalog for compatible types, operators and budgets.
|
|
354
|
+
|
|
355
|
+
### Detail Page value assignments (4.22)
|
|
356
|
+
|
|
357
|
+
`flowbase docs catalogs page-value-rules` describes authoring and the edit sequence. Page snapshots support `setFieldValue` and `setDefaultFieldValue`; sources can traverse up to five single-record relations. `pages evaluate` continues to preview field states and component visibility only.
|
|
358
|
+
|
|
359
|
+
Create and detail Page actions accept an optional explicit `conversion`: `mapOptions` with `mappings: [{sourceOptionId, targetOptionId}]`, `copyOptions` for the same multiple-select definition through a relation, `truncateDate` for lower date precision, or `extractDate` for datetime → date in Asia/Shanghai. Read the catalog for the complete contract. Mappings use stable identities, never option names. Partial mappings warn; an unmapped runtime value fails the entire action. Disabled rules may retain inactive targets but must retain valid identities. Ordinary record writes remain strict and do not implicitly execute these conversions.
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
flowbase records get OBJECT RECORD
|
|
363
|
+
flowbase records page-value-context OBJECT RECORD
|
|
364
|
+
flowbase docs example records.page-value-event --output event.json
|
|
365
|
+
# Fill event.json with the returned pageId/revision, current edit delta,
|
|
366
|
+
# changed field IDs, and the preceding event's sources (initially {}).
|
|
367
|
+
flowbase records page-value-event OBJECT RECORD --json-file event.json
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
Context and event calls require both record read and write scopes, and do not save edits. Inspect `errors`, apply returned `values` to your edit delta, and carry `sources` into the next event's `previousSources`. Values use field keys, changed fields use IDs, and decimal assignments are returned as lossless strings. Defaults skip nonempty targets. Source/condition changes trigger assignment; simply reading or saving does not.
|
|
371
|
+
|
|
372
|
+
Save the merged edit delta with `records update`, including `pageId`, `valueRuleRevision` (the context's `revision`), and `updatedAt`. Configuration changes or stale record versions reject the save; reload and reconcile on 409. Page rules and field permissions are rechecked without rerunning assignments. Whole-record edits use the existing `bundle-save` / `configVersion` contract. Production context uses published configuration, while test Hosts use effective configuration.
|
|
373
|
+
|
|
374
|
+
### Official app store (4.14)
|
|
375
|
+
|
|
376
|
+
Read `flowbase docs catalogs app-store`. Reads and checks require metadata read; install, publish and listing changes require metadata write and confirmation (`--yes` in automation).
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
flowbase app-store context
|
|
380
|
+
flowbase app-store list --query tasks --page 1
|
|
381
|
+
flowbase app-store get PACKAGE
|
|
382
|
+
flowbase docs example app-store.install-check --output installation.json
|
|
383
|
+
# Set the reviewed version and desired app name.
|
|
384
|
+
flowbase app-store install-check PACKAGE --json-file installation.json
|
|
385
|
+
# Copy version/name into install.json; add the returned check and a fresh UUID request_id.
|
|
386
|
+
flowbase app-store install PACKAGE --json-file install.json --yes
|
|
387
|
+
flowbase app-store installation REQUEST_UUID
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Installation requires a clean enabled environment and creates configuration drafts only. Review and release them separately. The check binds the current Host environment, source package, name, API key and authorization; it expires after 15 minutes. Changed inputs require another check. After a timeout, query the receipt before retrying; reuse a request ID only with the identical body. Inspect `status`/`error`, since HTTP success may report `processing` or `failed`. A failed attempt needs a new check and request ID.
|
|
391
|
+
|
|
392
|
+
For eligible official publishers on the production Host:
|
|
393
|
+
|
|
394
|
+
1. `app-store sources` discovers committed source apps; production drafts must be resolved first.
|
|
395
|
+
2. `app-store source-check --json '{"app_id":"APP"}'` returns a signed source snapshot.
|
|
396
|
+
3. `docs example app-store.publish-check --output publication.json` provides all required bilingual product fields. Fill them and the returned source, package ID and version, then run `app-store publish-check --json-file publication.json`.
|
|
397
|
+
4. Review product content and checked resources. Add `check`, a fresh UUID `request_id`, and `preview_confirmed: true`; run `app-store publish --json-file publish.json --yes`.
|
|
398
|
+
5. Query `app-store publication REQUEST_UUID` or `app-store publications`. Use `app-store listing PACKAGE --json '{"listed":false}' --yes` to withdraw, or `true` to relist.
|
|
399
|
+
|
|
400
|
+
Store request bodies use snake_case. `--yes` does not bypass publishing eligibility, production-only rules, portability validation or rechecks. These added commands need an updated CLI installation and a backend with the corresponding public routes; the package version is bumped separately during release.
|
|
328
401
|
|
|
329
402
|
### Reusable iframe configuration (4.11)
|
|
330
403
|
|
|
@@ -312,7 +312,7 @@ class FlowBaseCliTest(unittest.TestCase):
|
|
|
312
312
|
page_rules = json.loads(stdout.getvalue())
|
|
313
313
|
action_types = {item["type"] for item in page_rules["actions"]}
|
|
314
314
|
self.assertEqual(
|
|
315
|
-
action_types, {"setFieldState", "setComponentVisibility"}
|
|
315
|
+
action_types, {"setFieldState", "setComponentVisibility", "setDefaultFieldValue", "setFieldValue"}
|
|
316
316
|
)
|
|
317
317
|
visibility = next(
|
|
318
318
|
item
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|