@carthooks/arcubase-cli 0.1.3 → 0.1.5

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.
Files changed (64) hide show
  1. package/bundle/arcubase-admin.mjs +546 -243
  2. package/bundle/arcubase.mjs +546 -243
  3. package/dist/bin/arcubase-admin.js +0 -0
  4. package/dist/bin/arcubase.js +0 -0
  5. package/dist/generated/command_registry.generated.d.ts +36 -112
  6. package/dist/generated/command_registry.generated.d.ts.map +1 -1
  7. package/dist/generated/command_registry.generated.js +40 -163
  8. package/dist/generated/type_index.generated.d.ts +0 -12
  9. package/dist/generated/type_index.generated.d.ts.map +1 -1
  10. package/dist/generated/type_index.generated.js +0 -12
  11. package/dist/generated/zod_registry.generated.d.ts +1 -19
  12. package/dist/generated/zod_registry.generated.d.ts.map +1 -1
  13. package/dist/generated/zod_registry.generated.js +0 -21
  14. package/dist/runtime/command_registry.d.ts +19 -1
  15. package/dist/runtime/command_registry.d.ts.map +1 -1
  16. package/dist/runtime/command_registry.js +19 -1
  17. package/dist/runtime/errors.d.ts +1 -0
  18. package/dist/runtime/errors.d.ts.map +1 -1
  19. package/dist/runtime/execute.d.ts.map +1 -1
  20. package/dist/runtime/execute.js +321 -8
  21. package/dist/runtime/upload.d.ts +13 -0
  22. package/dist/runtime/upload.d.ts.map +1 -0
  23. package/dist/runtime/upload.js +148 -0
  24. package/dist/runtime/zod_registry.d.ts.map +1 -1
  25. package/dist/runtime/zod_registry.js +50 -30
  26. package/dist/tests/command_registry.test.js +11 -4
  27. package/dist/tests/execute_validation.test.js +221 -13
  28. package/dist/tests/help.test.js +29 -6
  29. package/dist/tests/upload.test.d.ts +2 -0
  30. package/dist/tests/upload.test.d.ts.map +1 -0
  31. package/dist/tests/upload.test.js +107 -0
  32. package/package.json +1 -1
  33. package/sdk-dist/api/admin/app.ts +8 -1
  34. package/sdk-dist/docs/runtime-reference/README.md +33 -15
  35. package/sdk-dist/docs/runtime-reference/app-discovery.md +68 -0
  36. package/sdk-dist/docs/runtime-reference/entity-schema/README.md +2 -2
  37. package/sdk-dist/docs/runtime-reference/entity-schema/file.md +9 -0
  38. package/sdk-dist/docs/runtime-reference/entity-schema/image.md +9 -0
  39. package/sdk-dist/docs/runtime-reference/entity-schema/subform.md +2 -2
  40. package/sdk-dist/docs/runtime-reference/entity-schema.md +2 -2
  41. package/sdk-dist/docs/runtime-reference/examples/README.md +1 -1
  42. package/sdk-dist/docs/runtime-reference/examples/oms-01/README.md +23 -4
  43. package/sdk-dist/docs/runtime-reference/examples/oms-01/app-overview.md +1 -1
  44. package/sdk-dist/docs/runtime-reference/row-crud.md +8 -6
  45. package/sdk-dist/docs/runtime-reference/search-and-bulk-actions.md +5 -5
  46. package/sdk-dist/docs/runtime-reference/table-lifecycle.md +34 -6
  47. package/sdk-dist/docs/runtime-reference/uploads.md +106 -0
  48. package/sdk-dist/generated/command_registry.generated.ts +40 -163
  49. package/sdk-dist/generated/type_index.generated.ts +0 -12
  50. package/sdk-dist/generated/zod_registry.generated.ts +0 -36
  51. package/sdk-dist/types/app.ts +7 -0
  52. package/src/generated/command_registry.generated.ts +40 -163
  53. package/src/generated/type_index.generated.ts +0 -12
  54. package/src/generated/zod_registry.generated.ts +0 -36
  55. package/src/runtime/command_registry.ts +38 -2
  56. package/src/runtime/errors.ts +1 -0
  57. package/src/runtime/execute.ts +368 -8
  58. package/src/runtime/upload.ts +196 -0
  59. package/src/runtime/zod_registry.ts +50 -30
  60. package/src/tests/command_registry.test.ts +13 -4
  61. package/src/tests/execute_validation.test.ts +257 -13
  62. package/src/tests/help.test.ts +35 -6
  63. package/src/tests/upload.test.ts +133 -0
  64. package/sdk-dist/docs/runtime-reference/workflow/README.md +0 -19
@@ -0,0 +1,107 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import fs from 'fs';
4
+ import os from 'os';
5
+ import path from 'path';
6
+ import { executeCLI } from '../runtime/execute.js';
7
+ const env = {
8
+ ARCUBASE_BASE_URL: 'https://arcubase.example.com',
9
+ ARCUBASE_TENANT_ID: 'tenant_1',
10
+ ARCUBASE_ACCESS_TOKEN: 'tok',
11
+ ARCUBASE_TRACE_ID: '',
12
+ ARCUBASE_SUBJECT_TYPE: '',
13
+ ARCUBASE_SUBJECT_ID: '',
14
+ ARCUBASE_TOKEN_EXPIRES_AT: '',
15
+ };
16
+ test('upload help works without runtime env', async () => {
17
+ const out = await executeCLI('user', ['upload', '--help'], undefined, async () => new Response('{}'));
18
+ assert.equal(out.kind, 'help');
19
+ assert.match(out.text, /arcubase upload <local-file>/);
20
+ assert.match(out.text, /uploads\.md/);
21
+ });
22
+ test('upload returns file field value array for row payloads', async () => {
23
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'arcubase-upload-'));
24
+ const sourceFile = path.join(tempDir, 'contract.pdf');
25
+ fs.writeFileSync(sourceFile, 'fake pdf bytes');
26
+ const calls = [];
27
+ const result = await executeCLI('user', ['upload', sourceFile], env, async (input, init) => {
28
+ const url = String(input);
29
+ calls.push({ url, method: init?.method });
30
+ if (url === 'https://arcubase.example.com/upload/token') {
31
+ return new Response(JSON.stringify({
32
+ data: {
33
+ id: 123456,
34
+ mode: 'aliyun-oss',
35
+ token_data: {
36
+ dir: 'upload/123456/',
37
+ policy: 'policy',
38
+ accessid: 'accessid',
39
+ signature: 'signature',
40
+ host: 'https://uploads.example.com',
41
+ },
42
+ },
43
+ }), { status: 200, headers: { 'Content-Type': 'application/json' } });
44
+ }
45
+ if (url === 'https://uploads.example.com') {
46
+ return new Response('', { status: 200 });
47
+ }
48
+ throw new Error(`unexpected fetch url: ${url}`);
49
+ });
50
+ assert.equal(result.kind, 'result');
51
+ assert.deepEqual(calls, [
52
+ { url: 'https://arcubase.example.com/upload/token', method: 'POST' },
53
+ { url: 'https://uploads.example.com', method: 'POST' },
54
+ ]);
55
+ assert.deepEqual(result.data, [
56
+ {
57
+ upload_id: 123456,
58
+ file: 'contract.pdf',
59
+ file_name: 'contract.pdf',
60
+ meta: {},
61
+ },
62
+ ]);
63
+ });
64
+ test('upload supports s3-post-policy tokens', async () => {
65
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'arcubase-upload-s3-'));
66
+ const sourceFile = path.join(tempDir, 'contract.pdf');
67
+ fs.writeFileSync(sourceFile, 'fake pdf bytes');
68
+ const calls = [];
69
+ const result = await executeCLI('user', ['upload', sourceFile], env, async (input, init) => {
70
+ const url = String(input);
71
+ calls.push({ url, method: init?.method });
72
+ if (url === 'https://arcubase.example.com/upload/token') {
73
+ return new Response(JSON.stringify({
74
+ data: {
75
+ id: 654321,
76
+ mode: 's3-post-policy',
77
+ token_data: {
78
+ dir: 'upload/654321/',
79
+ policy: 'policy',
80
+ host: 'https://uploads.example.com/private-bucket',
81
+ x_amz_algorithm: 'AWS4-HMAC-SHA256',
82
+ x_amz_credential: 'test/20260504/us-east-1/s3/aws4_request',
83
+ x_amz_date: '20260504T010203Z',
84
+ x_amz_signature: 'abc123',
85
+ },
86
+ },
87
+ }), { status: 200, headers: { 'Content-Type': 'application/json' } });
88
+ }
89
+ if (url === 'https://uploads.example.com/private-bucket') {
90
+ return new Response('', { status: 200 });
91
+ }
92
+ throw new Error(`unexpected fetch url: ${url}`);
93
+ });
94
+ assert.equal(result.kind, 'result');
95
+ assert.deepEqual(calls, [
96
+ { url: 'https://arcubase.example.com/upload/token', method: 'POST' },
97
+ { url: 'https://uploads.example.com/private-bucket', method: 'POST' },
98
+ ]);
99
+ assert.deepEqual(result.data, [
100
+ {
101
+ upload_id: 654321,
102
+ file: 'contract.pdf',
103
+ file_name: 'contract.pdf',
104
+ meta: {},
105
+ },
106
+ ]);
107
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carthooks/arcubase-cli",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Arcubase runtime CLI for admin and user command execution",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -13,7 +13,8 @@ import type {
13
13
  AppUpdateAppRespVO,
14
14
  AppUpdateI18nReqVO,
15
15
  AppUpdateI18nRespVO,
16
- AppGetEntitiesRespVO
16
+ AppGetEntitiesRespVO,
17
+ AppListRespVO
17
18
  } from '../../types/app'
18
19
  import type {
19
20
  AppDeleteWidgetsRespVO,
@@ -46,6 +47,12 @@ export async function createAppByTenants(
46
47
  return getDefaultClient().post('/apps', data)
47
48
  }
48
49
 
50
+ // @endpoint GET /apps
51
+ // @controller App.ListApps
52
+ export async function listApps(): Promise<AppListRespVO> {
53
+ return getDefaultClient().get('/apps')
54
+ }
55
+
49
56
  // @endpoint POST /apps/:id/entities
50
57
  // @controller App.CreateEntity
51
58
  export async function createEntity(
@@ -25,6 +25,7 @@ Do not start from raw HTTP methods or paths. Start from the CLI command.
25
25
 
26
26
  Use `arcubase-admin` for:
27
27
 
28
+ - app discovery
28
29
  - app creation
29
30
  - entity shell creation
30
31
  - entity schema save
@@ -33,6 +34,7 @@ Use `arcubase-admin` for:
33
34
  Common commands:
34
35
 
35
36
  ```bash
37
+ arcubase-admin app inventory
36
38
  arcubase-admin app create-app-by-tenants --body-file create-app.json
37
39
  arcubase-admin app create-entity --id <app_id> --body-file create-entity.json
38
40
  arcubase-admin entity admin-get-entity-info --app-id <app_id> --entity-id <entity_id>
@@ -54,16 +56,24 @@ Use `arcubase` for:
54
56
  Common commands:
55
57
 
56
58
  ```bash
57
- arcubase workflow insert-entity --app-id <app_id> --entity-id <entity_id> --body-file insert.json
58
- arcubase workflow query-entity --app-id <app_id> --entity-id <entity_id> --body-file query.json
59
- arcubase workflow update-entity-row --app-id <app_id> --entity-id <entity_id> --row-id <row_id> --body-file update.json
60
- arcubase workflow delete-entity-row --app-id <app_id> --entity-id <entity_id> --body-file delete.json
61
- arcubase workflow restore-entity-row --app-id <app_id> --entity-id <entity_id> --body-file restore.json
62
- arcubase workflow query-entity-selection --app-id <app_id> --entity-id <entity_id> --action archive --body-file selection.json
59
+ arcubase rows insert-entity --app-id <app_id> --entity-id <entity_id> --body-file insert.json
60
+ arcubase rows query-entity --app-id <app_id> --entity-id <entity_id> --body-file query.json
61
+ arcubase rows update-entity-row --app-id <app_id> --entity-id <entity_id> --row-id <row_id> --body-file update.json
62
+ arcubase rows delete-entity-row --app-id <app_id> --entity-id <entity_id> --body-file delete.json
63
+ arcubase rows restore-entity-row --app-id <app_id> --entity-id <entity_id> --body-file restore.json
64
+ arcubase rows query-entity-selection --app-id <app_id> --entity-id <entity_id> --action archive --body-file selection.json
63
65
  arcubase entity update-entity-bulk --app-id <app_id> --entity-id <entity_id> --body-file bulk-update.json
64
66
  arcubase entity invoke-entity-batch-operator --app-id <app_id> --entity-id <entity_id> --body-file invoke-batch-operator.json
65
67
  ```
66
68
 
69
+ Hard rule:
70
+
71
+ - all Arcubase work starts by identifying the target app
72
+ - `arcubase-admin` stops at schema save
73
+ - all row operations must switch to `arcubase`
74
+ - do not use `arcubase-admin` for row insertion or row queries
75
+ - do not ask the user for `entity_id` when creating a new table
76
+
67
77
  ## Required file inputs
68
78
 
69
79
  Most write commands use:
@@ -79,7 +89,7 @@ Use `--query-file` when the command needs query-string parameters that do not be
79
89
  Current important example:
80
90
 
81
91
  ```bash
82
- arcubase workflow query-entity \
92
+ arcubase rows query-entity \
83
93
  --app-id <app_id> \
84
94
  --entity-id <entity_id> \
85
95
  --query-file archived-query.json \
@@ -133,15 +143,22 @@ When a command is tied to a common task, `--help` should print:
133
143
 
134
144
  If you need to create a table:
135
145
 
136
- 1. read `table-lifecycle.md`
137
- 2. read `entity-schema.md`
138
- 3. read `entity-schema/README.md`
139
- 4. open the exact field-type page you need
146
+ 1. read `app-discovery.md`
147
+ 2. read `table-lifecycle.md`
148
+ 3. read `entity-schema.md`
149
+ 4. read `entity-schema/README.md`
150
+ 5. open the exact field-type page you need
151
+
152
+ If you need to find an existing app or choose the right app:
153
+
154
+ 1. read `app-discovery.md`
155
+ 2. run `arcubase-admin app inventory`
140
156
 
141
157
  If you need row CRUD:
142
158
 
143
159
  1. read `row-crud.md`
144
- 2. if a field is complex, open the exact field-type page
160
+ 2. if the row contains a file or image field, read `uploads.md`
161
+ 3. if a field is complex, open the exact field-type page
145
162
 
146
163
  If you need a business-shaped template:
147
164
 
@@ -156,6 +173,8 @@ If you need search, selection, tags, bulk update, or batch operator:
156
173
 
157
174
  ## Covered now
158
175
 
176
+ - `app-discovery.md`
177
+ - resolve the target app before asking the user for ids
159
178
  - `table-lifecycle.md`
160
179
  - app shell, entity shell, schema save, readiness probe
161
180
  - `entity-schema.md`
@@ -166,12 +185,11 @@ If you need search, selection, tags, bulk update, or batch operator:
166
185
  - one field cheatsheet per file
167
186
  - `row-crud.md`
168
187
  - insert, query, update, delete, restore
188
+ - `uploads.md`
189
+ - upload one local file and reuse the returned field value in row payloads
169
190
  - `search-and-bulk-actions.md`
170
191
  - search, selection, tags, bulk update, batch operator
171
192
  - `examples/`
172
193
  - business-shaped schema and payload templates
173
194
 
174
195
  ## Reserved expansion
175
-
176
- - `workflow/README.md`
177
- - reserved for future workflow-specific CLI docs
@@ -0,0 +1,68 @@
1
+ # App Discovery
2
+
3
+ Arcubase is a headless app platform.
4
+
5
+ Core concepts:
6
+
7
+ - app: the top-level business container
8
+ - entity: a table inside an app
9
+ - row: a record inside an entity
10
+
11
+ Hard rule:
12
+
13
+ - every operation happens inside one app
14
+ - find the target app before schema work or row work
15
+
16
+ Do not ask the user for `app_id` unless:
17
+
18
+ - there is no matching app
19
+ - there are multiple matching apps and you cannot resolve the ambiguity
20
+
21
+ Do not ask the user for `entity_id` when creating a new table.
22
+ Entity ids are assigned by Arcubase.
23
+
24
+ ## First command
25
+
26
+ Use the inventory command first:
27
+
28
+ ```bash
29
+ arcubase-admin app inventory
30
+ ```
31
+
32
+ It returns:
33
+
34
+ - every accessible app
35
+ - each app id and app name
36
+ - each app entity list
37
+
38
+ Use it to resolve:
39
+
40
+ - which existing app matches the user's business name
41
+ - whether the table already exists
42
+ - whether the user is talking about the wrong app
43
+
44
+ ## Resolution order
45
+
46
+ 1. if the user gives an app name, run `arcubase-admin app inventory`
47
+ 2. match the app by name yourself
48
+ 3. if the match is unique, continue without asking for `app_id`
49
+ 4. if there is no match, ask which app to use
50
+ 5. if there are multiple matches, ask the user to choose by app name
51
+
52
+ ## Existing app flow
53
+
54
+ If the app already exists:
55
+
56
+ 1. run `arcubase-admin app inventory`
57
+ 2. find the app id
58
+ 3. inspect the existing entity list
59
+ 4. decide whether to create a new entity or write rows into an existing entity
60
+
61
+ ## New app flow
62
+
63
+ If the user clearly wants a brand-new app:
64
+
65
+ 1. create the app with `arcubase-admin app create-app-by-tenants`
66
+ 2. create the entity shell
67
+ 3. save the schema
68
+ 4. switch to `arcubase rows ...` for row operations
@@ -54,8 +54,8 @@ If you need row payloads, read:
54
54
  Current important row rules:
55
55
 
56
56
  - row delete / restore uses:
57
- - `arcubase workflow delete-entity-row`
58
- - `arcubase workflow restore-entity-row`
57
+ - `arcubase rows delete-entity-row`
58
+ - `arcubase rows restore-entity-row`
59
59
  - `selection.type = "ids"`
60
60
  - `subform` row values use:
61
61
  - `[{ "id": 0, "fields": { ... } }]`
@@ -42,3 +42,12 @@ File upload field.
42
42
  - `count_range: false`
43
43
  - `count_min: 0`
44
44
  - `count_max: 9`
45
+
46
+ ## Row write rule
47
+
48
+ When inserting or updating row data for a `file` field:
49
+
50
+ - do not construct upload payload objects by hand
51
+ - run `arcubase upload <local-file>` first
52
+ - use the returned `data` array directly as the row field value
53
+ - read `../uploads.md`
@@ -41,3 +41,12 @@ Image upload field.
41
41
  - `count_range: false`
42
42
  - `count_min: 0`
43
43
  - `count_max: 9`
44
+
45
+ ## Row write rule
46
+
47
+ When inserting or updating row data for an `image` field:
48
+
49
+ - do not construct upload payload objects by hand
50
+ - run `arcubase upload <local-file>` first
51
+ - use the returned `data` array directly as the row field value
52
+ - read `../uploads.md`
@@ -43,8 +43,8 @@ Subform field.
43
43
 
44
44
  For row commands such as:
45
45
 
46
- - `arcubase workflow insert-entity`
47
- - `arcubase workflow update-entity-row`
46
+ - `arcubase rows insert-entity`
47
+ - `arcubase rows update-entity-row`
48
48
 
49
49
  the current writable row shape is:
50
50
 
@@ -30,7 +30,7 @@ The current direct-write path is:
30
30
  1. create the entity shell
31
31
  2. fetch the current shell
32
32
  3. save the full schema
33
- 4. probe rows with `arcubase workflow query-entity`
33
+ 4. probe rows with `arcubase rows query-entity`
34
34
 
35
35
  Do not treat shell creation as “table created”.
36
36
 
@@ -180,7 +180,7 @@ Also:
180
180
  Do not call schema creation successful until:
181
181
 
182
182
  1. `arcubase-admin entity admin-save-entity ...` succeeds without top-level `error`
183
- 2. `arcubase workflow query-entity ...` succeeds against the saved table
183
+ 2. `arcubase rows query-entity ...` succeeds against the saved table
184
184
 
185
185
  If row probing still fails, the table is not ready.
186
186
 
@@ -16,7 +16,7 @@ These examples are not raw tenant exports.
16
16
 
17
17
  - Keep table names and field names in English.
18
18
  - Remove company-specific words.
19
- - Remove region-specific words when they are not essential to the workflow.
19
+ - Remove region-specific words when they are not essential to the business process.
20
20
  - Prefer neutral names such as `sku_code`, `sales_order`, `goods_receipt`, and `stock_issue`.
21
21
  - When a save payload needs shell values, replace placeholder tokens such as `__APP_ID__`, `__ENTITY_ID__`, and `__SCHEMA_VERSION__` from the current shell returned by:
22
22
 
@@ -1,6 +1,6 @@
1
1
  # OMS Example 01
2
2
 
3
- This example set models a compact order-management workflow.
3
+ This example set models a compact order-management example.
4
4
 
5
5
  It is intentionally generic:
6
6
 
@@ -70,7 +70,7 @@ This example rewrites them into generic names such as:
70
70
  - `sales-order.selection.condition.json`
71
71
  - `sales-order.bulk-update.json`
72
72
 
73
- ## Save workflow
73
+ ## Save sequence
74
74
 
75
75
  For every `*.schema.json` file:
76
76
 
@@ -85,6 +85,25 @@ For every `*.schema.json` file:
85
85
 
86
86
  These schema files are templates, not live shell exports.
87
87
 
88
+ ## CLI phases
89
+
90
+ Phase 1 uses `arcubase-admin`:
91
+
92
+ - create the app
93
+ - create entity shells
94
+ - fetch shells
95
+ - save schemas
96
+
97
+ Phase 2 uses `arcubase`:
98
+
99
+ - insert rows
100
+ - query rows
101
+ - update rows
102
+ - delete or restore rows
103
+ - search, selection, and bulk actions
104
+
105
+ Do not use `arcubase-admin` for row operations.
106
+
88
107
  ## Minimal command path
89
108
 
90
109
  Create the app:
@@ -124,13 +143,13 @@ arcubase-admin entity admin-save-entity --app-id <app_id> --entity-id <entity_id
124
143
  Insert one row:
125
144
 
126
145
  ```bash
127
- arcubase workflow insert-entity --app-id <app_id> --entity-id <entity_id> --body-file sales-order.row.insert.json
146
+ arcubase rows insert-entity --app-id <app_id> --entity-id <entity_id> --body-file sales-order.row.insert.json
128
147
  ```
129
148
 
130
149
  Query rows:
131
150
 
132
151
  ```bash
133
- arcubase workflow query-entity --app-id <app_id> --entity-id <entity_id> --body-file sales-order.query.json
152
+ arcubase rows query-entity --app-id <app_id> --entity-id <entity_id> --body-file sales-order.query.json
134
153
  ```
135
154
 
136
155
  ## Placeholder rules
@@ -76,4 +76,4 @@ Purpose:
76
76
  - country-specific code naming
77
77
  - tenant-specific internal labels
78
78
  - region-specific channel names
79
- - company-specific workflow terms
79
+ - company-specific process terms
@@ -7,7 +7,7 @@ Use this page for direct row operations with `arcubase`.
7
7
  Command:
8
8
 
9
9
  ```bash
10
- arcubase workflow insert-entity \
10
+ arcubase rows insert-entity \
11
11
  --app-id <app_id> \
12
12
  --entity-id <entity_id> \
13
13
  --body-file insert.json
@@ -29,6 +29,7 @@ Rules:
29
29
 
30
30
  - use numeric field ids as JSON object keys
31
31
  - values must match the saved schema
32
+ - if a field is `file` or `image`, run `arcubase upload <local-file>` first and use the returned `data` array as the field value
32
33
 
33
34
  Success result:
34
35
 
@@ -45,7 +46,7 @@ The returned value is the new `row_id`.
45
46
  Command:
46
47
 
47
48
  ```bash
48
- arcubase workflow query-entity \
49
+ arcubase rows query-entity \
49
50
  --app-id <app_id> \
50
51
  --entity-id <entity_id> \
51
52
  --body-file query.json
@@ -84,7 +85,7 @@ Typical row shape:
84
85
  Command:
85
86
 
86
87
  ```bash
87
- arcubase workflow get-entity-row \
88
+ arcubase rows get-entity-row \
88
89
  --app-id <app_id> \
89
90
  --entity-id <entity_id> \
90
91
  --row-id <row_id>
@@ -97,7 +98,7 @@ Use this when you already know the row id and want the full record payload.
97
98
  Command:
98
99
 
99
100
  ```bash
100
- arcubase workflow update-entity-row \
101
+ arcubase rows update-entity-row \
101
102
  --app-id <app_id> \
102
103
  --entity-id <entity_id> \
103
104
  --row-id <row_id> \
@@ -121,6 +122,7 @@ Rules:
121
122
  - `changed_fields` is required
122
123
  - every id in `changed_fields` must also appear in `data`
123
124
  - use numeric field ids as JSON object keys
125
+ - if a field is `file` or `image`, run `arcubase upload <local-file>` first and use the returned `data` array as the field value
124
126
 
125
127
  Success result:
126
128
 
@@ -137,7 +139,7 @@ The update command returns `true`, not the updated row body.
137
139
  Command:
138
140
 
139
141
  ```bash
140
- arcubase workflow delete-entity-row \
142
+ arcubase rows delete-entity-row \
141
143
  --app-id <app_id> \
142
144
  --entity-id <entity_id> \
143
145
  --body-file delete.json
@@ -165,7 +167,7 @@ Rules:
165
167
  Command:
166
168
 
167
169
  ```bash
168
- arcubase workflow restore-entity-row \
170
+ arcubase rows restore-entity-row \
169
171
  --app-id <app_id> \
170
172
  --entity-id <entity_id> \
171
173
  --body-file restore.json
@@ -14,7 +14,7 @@ Use this page for:
14
14
  Use:
15
15
 
16
16
  ```bash
17
- arcubase workflow query-entity \
17
+ arcubase rows query-entity \
18
18
  --app-id <app_id> \
19
19
  --entity-id <entity_id> \
20
20
  --body-file query.json
@@ -83,7 +83,7 @@ Archived view requires both:
83
83
  Command:
84
84
 
85
85
  ```bash
86
- arcubase workflow query-entity \
86
+ arcubase rows query-entity \
87
87
  --app-id <app_id> \
88
88
  --entity-id <entity_id> \
89
89
  --query-file archived-query.json \
@@ -195,7 +195,7 @@ Rules:
195
195
  Command:
196
196
 
197
197
  ```bash
198
- arcubase workflow query-entity-selection \
198
+ arcubase rows query-entity-selection \
199
199
  --app-id <app_id> \
200
200
  --entity-id <entity_id> \
201
201
  --action query \
@@ -235,7 +235,7 @@ Rules:
235
235
  Command:
236
236
 
237
237
  ```bash
238
- arcubase workflow query-entity-selection \
238
+ arcubase rows query-entity-selection \
239
239
  --app-id <app_id> \
240
240
  --entity-id <entity_id> \
241
241
  --action archive \
@@ -253,7 +253,7 @@ Rules:
253
253
  Command:
254
254
 
255
255
  ```bash
256
- arcubase workflow query-entity-selection \
256
+ arcubase rows query-entity-selection \
257
257
  --app-id <app_id> \
258
258
  --entity-id <entity_id> \
259
259
  --action batch_print \
@@ -2,6 +2,7 @@
2
2
 
3
3
  Use this page when the goal is:
4
4
 
5
+ - find the target app
5
6
  - create an app
6
7
  - create a table
7
8
  - save the schema
@@ -9,14 +10,36 @@ Use this page when the goal is:
9
10
 
10
11
  The successful path is command-first:
11
12
 
12
- 1. create the app
13
- 2. create the entity shell
14
- 3. fetch the current shell
15
- 4. save the full schema
16
- 5. probe rows with `query-entity`
13
+ 1. identify the target app
14
+ 2. create the app
15
+ 3. create the entity shell
16
+ 4. fetch the current shell
17
+ 5. save the full schema
18
+ 6. probe rows with `query-entity`
17
19
 
18
20
  Do not stop at shell creation.
19
21
 
22
+ CLI phase split:
23
+
24
+ - schema phase uses `arcubase-admin`
25
+ - row phase uses `arcubase`
26
+ - the switch happens immediately after `admin-save-entity`
27
+ - do not use `arcubase-admin` for row insert or row query
28
+
29
+ ## Step 0: identify the target app
30
+
31
+ Command:
32
+
33
+ ```bash
34
+ arcubase-admin app inventory
35
+ ```
36
+
37
+ Rules:
38
+
39
+ - always resolve the app first when the user refers to an existing app by name
40
+ - do not ask for `app_id` unless there is no match or more than one match
41
+ - do not ask for `entity_id` when creating a new table
42
+
20
43
  ## Step 1: create the app
21
44
 
22
45
  Command:
@@ -97,12 +120,17 @@ Read before writing `save-entity.json`:
97
120
  2. `entity-schema/README.md`
98
121
  3. the exact field-type pages you need
99
122
 
123
+ After `admin-save-entity`, switch binaries:
124
+
125
+ - use `arcubase rows insert-entity` for row insertion
126
+ - use `arcubase rows query-entity` for readiness and row reads
127
+
100
128
  ## Step 5: probe readiness
101
129
 
102
130
  Command:
103
131
 
104
132
  ```bash
105
- arcubase workflow query-entity \
133
+ arcubase rows query-entity \
106
134
  --app-id <app_id> \
107
135
  --entity-id <entity_id> \
108
136
  --body-file query.json