openxiangda-skill-kit 2.0.0-alpha.132 → 2.0.0-alpha.134

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openxiangda-skill-kit",
3
- "version": "2.0.0-alpha.132",
3
+ "version": "2.0.0-alpha.134",
4
4
  "description": "Validation and deterministic packaging for OpenXiangda 2.0 AI skills.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -17,7 +17,7 @@
17
17
  "README.md"
18
18
  ],
19
19
  "dependencies": {
20
- "openxiangda-devkit-core": "2.0.0-alpha.107"
20
+ "openxiangda-devkit-core": "2.0.0-alpha.109"
21
21
  },
22
22
  "devDependencies": {
23
23
  "tsx": "4.23.12",
@@ -5,7 +5,7 @@
5
5
  | Command | Risk | Purpose |
6
6
  | --- | --- | --- |
7
7
  | `pnpm openxiangda create` | deploy | 创建、绑定并初始化应用 |
8
- | `pnpm openxiangda dev` | write-local | 连接平台测试数据启动本地 Web Nest |
8
+ | `pnpm openxiangda dev` | write-local | 连接平台测试数据启动本地 Web,按需启动 Nest |
9
9
  | `pnpm openxiangda check` | write-local | 生成契约并在目标平台预检后执行检查、测试和构建 |
10
10
  | `pnpm openxiangda accept` | deploy | 按计划准备可选的真实预发验收身份 |
11
11
  | `pnpm openxiangda deploy` | deploy | 部署测试环境或显式复用测试版本部署生产 |
@@ -60,14 +60,18 @@ const visitorReservations = {
60
60
  };
61
61
  ```
62
62
 
63
- Put it in `data: { resources: [visitorReservations] }`. Resource CRUD
64
- capabilities are derived by `resourceCapabilityCodes`. For a Native resource,
65
- grant `read` to each role that may enter its generated page; the compiler also
66
- grants that role every enabled generated create/update/delete operation. Remove
67
- an operation only when the role must be restricted, using the corresponding
68
- code in `deniedCapabilities`. The compiler validates the denial and seals only
69
- the resulting allow list, so runtime authorization has no second deny model.
70
- Non-Native mutation owners never receive this expansion. Directory-backed roles also require
63
+ New applications compose `defineDataModel`, `defineResourceList`, `defineResourceForm`
64
+ and `defineApplicationModule` through the root `modules` property. A model alone
65
+ creates storage, never a page or menu. Select `crud: [{ model: model.code }]` only
66
+ when a standard CRUD page serves a business task. The existing `data.resources`
67
+ shape shown above remains a low-level input to the same compiler.
68
+
69
+ Use `resourceRoleCapabilities(appCode, resourceCode, 'read' | 'manage' | [operations])`
70
+ for explicit grants. Reading a page never implicitly grants create/update/delete.
71
+ Use `manage` only for a confirmed management role. Existing alpha roles that relied
72
+ on implicit expansion must declare their intended operations before regenerating.
73
+ `deniedCapabilities` subtracts explicit grants and is removed from the sealed role.
74
+ Directory-backed roles also require
71
75
  `app:<app-code>:directory:read`. Explicit field `access` capability codes are
72
76
  also granted only to the intended roles. They are owned and exported by the
73
77
  generated field policy, so do not repeat them in `authz.capabilities`.
@@ -11,18 +11,23 @@ imports at 100 rows per transaction, use exact declared labels or field codes,
11
11
  and leave attachment values to the platform managed-file component.
12
12
 
13
13
  Declare searchable and filterable fields on the resource and let the standard
14
- CRUD renderer compose the search area. Keyword search spans the declared
15
- searchable fields; the first two filters remain inline and additional filters
16
- open in the platform's large modal. The renderer also preserves declaration
17
- order for form fields and removes authorization/debug explanations from the
18
- business UI. Do not create application-owned search toolbars, field ordering
19
- maps, permission tips or per-resource CRUD pages for these standard behaviors.
14
+ CRUD renderer compose one toolbar. Keyword search spans the declared searchable
15
+ fields; all declared filters open on demand in the platform modal. Business
16
+ columns are the default; audit columns and density are optional list settings.
17
+ Desktop create/edit opens a drawer over the retained list; existing full-page
18
+ routes use the same form lifecycle. The renderer retains values after failed
19
+ saves, prevents repeated submission and asks before discarding an edited form.
20
+ Declare shared form/detail groups in `crud[].sections` with `title` and `fields`.
21
+ Form/detail field selections remain exhaustive and ordered. Use lightweight
22
+ section headings, two ordinary columns on PC and one on mobile; small forms
23
+ need no artificial group. Do not copy a list/form renderer or add application
24
+ search toolbars, field ordering maps or authorization/debug explanations.
20
25
 
21
26
  Read the current user, complete application-role union and capabilities from the platform runtime authorization endpoint. There is no application-selected active role or identity switch. The standard Shell owns the optional Perspective selector. Use `hasReadCapability` for navigation, list/detail visibility and readable fields; continue to use `hasCapability` for create/update/delete, workflows and custom actions. The standard client sends the selected Perspective automatically, and the server repeats the projection for rows, fields and RLS. Never implement resource-specific frontend filters for it. Strip unauthorized fields from create and update payloads and never treat a disabled input as server authorization. Verify with `pnpm openxiangda check`.
22
27
 
23
28
  Use the standard `Shell` unchanged. It owns the authenticated user's display
24
29
  name, account identifier, safe avatar upload, localized application-role names,
25
- theme controls, Perspective selection and navigation scroll restoration. It
30
+ Perspective selection, collapsible menu groups and navigation scroll restoration. It
26
31
  also owns directory field requests under the current logged-in user's role
27
32
  union. Never fetch identity for the header, display role codes, add a second
28
33
  identity selector, or copy Shell and
@@ -98,16 +103,11 @@ alias, or build the destination in the browser. Omitting the declaration means
98
103
  there is no application business-record target; a broken published mapping
99
104
  fails closed.
100
105
 
101
- The platform also owns admin appearance. Wrap bespoke admin content in
102
- `OpenXiangdaAdminPage`. Ant Design components inherit the existing
103
- `ConfigProvider`; do not create another theme provider. Use
104
- `useOpenXiangdaTheme()` for TypeScript-rendered values such as chart colors and
105
- the public `--oxa-color-*`, `--oxa-shadow-surface`, and
106
- `--oxa-radius-surface` variables for custom CSS. Never hard-code white, black,
107
- or neutral greys as admin canvas, card, border, or text colors. Application
108
- brand and categorical colors may remain explicit only when they are not used as
109
- structural theme colors. Verify every custom admin page in light, dark, and
110
- follow-system modes.
106
+ Wrap bespoke admin content in `OpenXiangdaAdminPage` and use Ant Design default
107
+ components. The platform UI provider supplies Chinese locale and contextual
108
+ feedback only. Do not generate appearance preferences, color settings or palette
109
+ registries. Keep component CSS scoped and verify real PC/mobile interactions,
110
+ including selectors, dialogs, form submission and failure recovery.
111
111
 
112
112
  Declare application-owned login visuals with optional
113
113
  `frontend.authentication`. The only supported account contract is
@@ -271,3 +271,25 @@ UUIDs or revision/event diagnostics. Treat `stale` as metadata and show the
271
271
  friendly refresh prompt only after a real command token/CAS conflict. Do not
272
272
  copy the standard page into an application merely to show full business fields
273
273
  or rearrange platform-owned operations.
274
+
275
+ ## Foundation module and field selection
276
+
277
+ New applications plan task pages first and compose data models and selected CRUD
278
+ views through `defineApplicationModule`. Internal tables need no page. List, form
279
+ and detail selections are exhaustive; `hidden` controls presentation independently
280
+ of Data API permissions. Keep root configuration short by importing business modules.
281
+
282
+ Use platform Field Kit before custom input controls. PC input may use `antd`;
283
+ mobile input uses the scoped `openxiangda/mobile` Ant Design Mobile adapter, inside
284
+ `MobileSurface` with `openxiangda/mobile/styles.css` (already included in React styles).
285
+ Do not import the `antd-mobile` root, which resets global page styles.
286
+ Do not write raw business input/select/textarea or
287
+ contentEditable elements. Keep mobile entrypoints in src/mobile/, Mobile*.tsx or
288
+ *.mobile.tsx so the application check can inspect their static local imports.
289
+ Basic text/number/boolean/option/date controls have a mobile adapter; complex field
290
+ migration remains staged, and each field must pass actual interaction acceptance.
291
+
292
+
293
+ 标准列表使用高级条件分组、显示列浮层、冻结和拖动列序、多排序。仅从页面声明的可读业务字段提供选择;导出与列表共用条件和排序。依赖所选记录的 toolbar contribution 声明 `requiresSelection: true`。显示列修改即时预览,显式保存个人偏好。
294
+
295
+ 标准表单使用“暂存 / 提交”及平台草稿箱,不自行使用 localStorage、业务表或 Nest 保存草稿。PC 抽屉头部提供全屏、新开页面、关闭;新开页面由平台保存并交接草稿。移动端为分组字段行、简单标题和固定底部操作,草稿/恢复确认用移动底部弹层;不显示“返回列表”。草稿字段必须保持权限裁剪,编辑草稿不得用最新 revision 覆盖原编辑版本。
@@ -1,35 +1,20 @@
1
1
  # OpenXiangda 2.0 Application Agent Contract
2
2
 
3
3
  - Use only the workspace-pinned CLI: `pnpm openxiangda <command>`. Never invoke a bare global `openxiangda` inside a 2.0 task.
4
- - `appspec/` is the optional OpenXiangda 2.0 business-intent layer. Before changing observable behavior, read the bounded index with `pnpm openxiangda spec context --json`, then select only the relevant stable ID; use no ChangeSpec for L0 work, one short ChangeSpec for L1, and add permission/rollback/concurrency detail only for L2/L3. Before close, the user—not AI—confirms `currentSpec=merged` or `not-applicable`. AppSpec is advisory and never a release gate. Never read, import or migrate 1.x `openspec/` or SDD.
5
- - Use Vite, React Router, Refine Core and Ant Design. Do not add Umi, ProComponents or another admin shell.
6
- - The platform `openxiangda/react` owns the only admin `ConfigProvider` and the
7
- `light`/`dark`/`system` appearance preference. Admin pages use Ant Design's
8
- `defaultAlgorithm`/`darkAlgorithm`, `theme.useToken()`, or generated
9
- `--oxa-antd-*` CSS variables. Do not add a nested theme provider, theme
10
- store, palette editor, `--oxa-color-*`/`--oxa-shell-*` aliases, or fixed
11
- white/black/neutral structural colors. Future palettes are centralized
12
- platform seed configurations; alpha contracts are replaced directly without
13
- compatibility aliases. User-end pages are outside this admin visual contract
14
- and may use Tailwind CSS and their own product design tokens/components, but
15
- must not mutate the admin provider or Seed.
16
- - Use the complete Ant Design Seed/Map/Alias/Component model on admin pages:
17
- platform-owned Seed values feed the selected algorithm; admin code consumes
18
- generated Alias values for colors, spacing, typography, control dimensions,
19
- motion, shadows, z-index and breakpoints. Never hand-write Map values or
20
- introduce an admin token registry. Component tokens are only for
21
- platform-approved non-color dimensions and typography.
22
- - The template includes Tailwind CSS v4 for user-end pages. Keep its `@theme`
23
- and utility classes in the user-end layer, omit Tailwind preflight from the
24
- admin shell, and do not make user-end utilities depend on `--oxa-antd-*`.
4
+ - Maintain business goals, task pages, permission decisions and acceptance examples in the existing `appspec/app.md`; complex modules may have focused capability records. `appspec/` is the OpenXiangda 2.0 business-intent layer. Before changing observable behavior, read the bounded index with `pnpm openxiangda spec context --json`, then select only the relevant stable ID; use no ChangeSpec for L0 work, one short ChangeSpec for L1, and add permission/rollback/concurrency detail only for L2/L3. Before close, the user—not AI—confirms `currentSpec=merged` or `not-applicable`. AppSpec is advisory and never a release gate. Never read, import or migrate 1.x `openspec/` or SDD.
5
+ - Use Vite, React Router, Refine Core and platform Field Kit. Use Ant Design for PC and the scoped openxiangda/mobile adapter for touch controls; wrap custom mobile pages in MobileSurface and import openxiangda/mobile/styles.css. Do not import the antd-mobile root with its global reset. Do not author raw business input/select/textarea/contentEditable elements. Keep mobile entrypoints under src/mobile/ or name them Mobile*.tsx / *.mobile.tsx so openxiangda check can inspect their local dependency graph. Do not add Umi, ProComponents or another admin shell.
6
+ - Use Ant Design's default component appearance on PC and the platform's scoped mobile adapter for touch controls. The UI provider supplies Chinese locale and contextual feedback only. Do not generate appearance preferences, color configuration, palette registries, visual state stores or document-wide color effects. Prefer platform components and keep CSS scoped to the component.
7
+ - The template includes Tailwind CSS v4 utilities for user pages. The application owns its minimal document reset; omit preflight from the shared runtime and do not scaffold custom palettes.
25
8
  - Bind every generated `appRoutes` entry to its local page with `defineApplicationContributions`; desktop `admin` routes stay inside the platform Shell, while `user` routes render without an admin Shell for independent mobile/user experiences. Generated resource CRUD routes are compiler-owned under `/admin/resources/<resourceCode>...` and `/m/admin/resources/<resourceCode>...`; never recreate root resource paths, aliases or redirects. Explicit routes that have the same canonical shape as another explicit or generated route fail compilation, even when dynamic parameter names differ. Use only the typed `toolbar`, `row` and `detail` resource slots for generated resource actions. Declare the complete editable admin menu with `defineAdminNavigation` and its page/group helpers; the Shell renders only generated `adminNavigation` references and permissions only filter them. Do not create another router, menu store, layout, identity provider, permission store or copied CRUD page; route/action access uses capability or `allOf`/`anyOf`, while Data/App API and Workflow authorization remain server-owned.
26
9
  - Application login is optional `frontend.authentication`: existing platform users only, registration rejected, exact desktop `/login` and mobile `/m/login`. Bind generated `authenticationSurfaces` to separate PC/mobile renderers through `defineApplicationContributions`; renderers own only brand visuals and call `ApplicationLoginSurfaceProps`. The platform alone owns passwords, providers, OAuth state/callbacks, secure cookies, current identity and authorization. Never put login in protected `appRoutes`, call a v1 auth route, store tokens, create users/roles, or add another Router/identity provider. Keep QA in generated `platformAuthManifest`, outside the protected route denominator.
27
10
  - Branded standard user pages use the optional exact `standardUserSurfaces` contribution from `openxiangda/react`: provide separate desktop/mobile `frame` and `applicationTodoCenter` renderers or omit the property entirely. The platform still owns `/todos`, `/m/todos`, Workflow routes, `RuntimeBoundary`, current-user Notification Hub data, query/load/interaction callbacks and navigation. Never add a second Router, Todo API client, identity store or token prop.
28
11
  - External users without platform accounts use only an exact static `surface: 'user'` route declared through `frontend.publicAccess`. Declare the one resource, bounded field sets, required operations, draft limits and named duplicate validations; consume only generated `anonymousPublicAccess` and `createAnonymousPublicClient`. `own.list`/`own.read` mean records submitted by the same platform-issued HttpOnly browser credential, not a verified natural person, and another browser or cleared cookie intentionally loses access. Never create a guest role/user, call the general Native Data API, expose an anonymous upload path, store identity locally or derive ownership from IP, user-agent or fingerprint.
29
- - Declare each resource once in `openxiangda.config.ts` with only `code`, `name`, `fields` and optional `mutationOwner`, generated/list/layout/data-policy settings. A Workflow subject resource may additionally declare `detailRouteCode: { desktop, mobile }`; both values reference explicit authenticated user routes that require the resource read capability, use the correct `/m` family and contain exactly one dynamic record parameter. This is the only business-record navigation source: never infer `/<resourceCode>/<recordId>` or add an alias. Each field owns type, label, required state, Surface flags, reference/file metadata and access. Resource codes are lower kebab-case. Use `native` for direct Data API mutations, `action`, `readonly` or `workflow` for non-Native ownership; never grant or generate Native mutation for a non-Native owner.
12
+ - Define storage with `defineDataModel` in `modules/<business>/models.ts`; compose modules with `defineApplicationModule`. Select standard pages explicitly through `crud`, `defineResourceList` and `defineResourceForm`. Models without `crud` receive no pages or navigation. A business task page may consume several models. The root `openxiangda.config.ts` composes modules, routes and roles; it must not grow into one giant business definition. Existing `data.resources` remains a lower-level input to the same compiler. Keep internal fields `hidden: true`; this is presentation, never authorization. `system: true` marks server-owned values and hides them by default; `hidden: false` may show a business status or serial number. Form/detail/list field selections are exhaustive and ordered. A Workflow subject resource may declare explicit desktop/mobile `detailRouteCode` as documented in the workflow contract.
30
13
  - Never write resource-level `schemaVersion`, `appCode`, `schema`, `surface`, `capabilities`, `fieldPolicies` or `platform/data` modules. The compiler derives the strict DataResource, CRUD capabilities, Surface and AI Schema. The application manifest still starts with its one top-level `schemaVersion: 3`.
31
14
  - Ordinary list/get/create/update/delete, filters, export and batch operations use the platform Native Data API. Do not create Function CRUD or NestJS wrappers.
32
- - Add NestJS only for a named business action that needs a cross-resource transaction, an invariant or an external side effect.
15
+ - Standard PC lists use one toolbar, on-demand filters/column settings and drawer create/edit over the retained list. Full-page entry uses the same platform form. Declare shared form/detail groups with `crud[].sections: [{ title, fields }]`; each view's field selection remains exhaustive and ordered. Small forms may omit groups. Keep only business columns by default, use lightweight sections and let platform components handle pending, errors and dirty cancellation. Do not recreate list/form layouts in application code.
16
+ - Add NestJS only for a named business action that needs a cross-resource transaction, an invariant or an external side effect. The blank app contains no apps/server source or Nest dependency importer. Declare backend.enabled or a server operation, then run pnpm openxiangda check or pnpm dev to initialize and install the optional backend once; existing source is never regenerated. Standard platform workflow definitions and activations do not require Nest.
17
+ - One model can declare up to 20 named standard views with `crud[].code` and `name`. Each selects its own list/form/detail fields, sections, generated operations and mobile availability. Bind navigation with `adminResourcePage(modelCode, { viewCode })`; only an unnamed CRUD declaration generates the original default routes. Views share model values, access and Data API ownership. Include writable required fields in create forms or set `generated.create: false`. Keep platform display preferences and authenticated drafts scoped to the selected view; do not copy models or invent a second draft store.
33
18
  - Every interactive business action binds `@OpenXiangdaOperation(operation)` and injects `OpenXiangdaBusinessDataApiService`, `OpenXiangdaBusinessNotificationService`, or `OpenXiangdaStandardOperations`. The platform checks the action capability once at App API ingress; the trusted backend then has full Data/managed business-notification access only to its exact application/environment while audit retains the initiating user and action. Do not author `authorizationJSON`, forward user tokens, grant ordinary users `app:notification2:send`, or reapply the user's resource, row and field permissions inside the action.
34
19
  - A NestJS backend declares only `enabled`, `isolation: 'shared' | 'dedicated'` and `resourceProfile: 'light' | 'standard'`. Never put raw Kubernetes resources, replicas, ports or environment maps in application metadata; the platform owns capacity and scaling.
35
20
  - Use the current logged-in user and the union of that user's application roles. An app for every logged-in platform user may declare one existing package role through `authz.authenticatedUserRoleCode`; the platform materializes it on first access and unions it with manual and business-projected roles. Do not fabricate a browser fallback role or use a business membership resource for this universal audience. An optional declared Perspective projects only read visibility (pages, rows and fields); create/update/delete, workflows and custom actions continue to authorize against the complete union. Standard Data API calls inherit `X-OpenXiangda-Perspective` automatically. Use `@CurrentPerspective()` only when custom Nest code reads outside the standard Data API, and apply an equivalent read projection explicitly. Business code must not persist a platform Token or authorization result and must not implement a second identity path.
@@ -41,8 +26,37 @@
41
26
  - Visitor duplicate protection uses `createVisitorReservation({ duplicateMatch: { fieldCode: submittedValue }, ... })`. `duplicateMatch` is a non-empty value map, never a field-name array, and no mutable pre-read is allowed.
42
27
  - Desktop and mobile pages share values, validation and authorization, but use separate renderers. Options, members and departments store display snapshots; resource references store direct JSON display values; attachments, images and signatures use platform-managed file references.
43
28
  - `option.*`, `user.*`, `department.*` and `resource-ref.*` values never collapse to scalar IDs. Single values store one labeled object and multiple values store object arrays. `resource-ref.*` JSON is not a foreign key, trusted target snapshot or automatically refreshed copy; current target state is read by `resourceCode` plus `value`. A resource source `labelField` must be `text.short` or `text.long`; `serial-number` is allowed in source search, description and snapshot fields, but not as the label. `location` accepts only exact WGS84 coordinates captured by DingTalk or browser geolocation; it has no manual input or `manual` source. Roles that consume directory-backed fields explicitly include `app:<app-code>:directory:read`.
44
- - Derive role grants with `resourceCapabilityCodes(appCode, resourceCode)`. Grant a Native resource's `read` capability to every role allowed to enter its generated page; the compiler adds enabled generated create/update/delete capabilities by default. Tighten only exceptional roles with `deniedCapabilities`, which is compile-time authoring input and is removed from the sealed role. Non-Native mutation owners never receive this expansion. Declare current-user rows only with `currentUserDataPolicy(...)`; do not invent operators, values or alternate current-user spellings.
29
+ - Use `resourceRoleCapabilities(appCode, resourceCode, "read" | "manage" | [operations])` for explicit role grants. A read grant never expands into create/update/delete when a page is added. Confirm the business permission matrix before implementing multi-role behavior; `manage` is only for roles explicitly allowed all CRUD operations. Use `currentUserDataPolicy(...)` for current-user row scope.
45
30
  - Do not add compatibility aliases, migration branches or silent fallbacks for an earlier 2.0 alpha contract. Replace an incorrect contract and regenerate the application.
46
31
  - Standard Workflow and Notification Hub are optional 2.0 modules. Enable them only through canonical `openxiangda.config.ts` declarations and generated clients. `standalone`/`hidden-handoff` default to the compiler-owned process operation; action-owned submission must instead declare `launch.submission.kind: 'named-operation'` with sealed create/existing input and output bindings so the standard PC/mobile page calls the original Named Action and accepts an explicit no-Workflow result. Never add a browser save callback or call Workflow prepare/start directly. Custom pages launch only through a verified Named Action using `OpenXiangdaBusinessProcessService`. PC and mobile render the same `ProcessCommandSurface` independently and recover only by `commandId`. To replace Workflow detail, declare both desktop and mobile `detailRouteCode` values whose routes contain exactly `:instanceId`. Add the current-user todo page only with `frontend.user.applicationTodoCenter: true`; never query Notification Hub management APIs from a user page.
47
32
  - Run `pnpm openxiangda check --json` after contract changes and read `data.sealedArtifact`; check never seals, and an older `.openxiangda/build/app-package.json` is not the current check result. Use `pnpm openxiangda accept --plan <file>` only for optional real preproduction identity acceptance; it never blocks delivery. Deploy with `pnpm openxiangda deploy`, inspect with `pnpm openxiangda status` and `pnpm openxiangda logs`, and use the platform rollback command rather than mutating K3s directly.
48
33
  - AI-native clients start the workspace protocol through the same pinned binary: `pnpm exec openxiangda --mcp-stdio --cwd <workspace>`. Read `openxiangda://workspace/contracts` or call `contract_describe`; for first-time menu authoring, copy `data.adminNavigationAuthoring.suggestion.expression` once into `frontend.admin.navigation` with its listed `openxiangda/config` imports, then edit that application-owned declaration. Never treat the proposal as runtime discovery. When AppSpec is enabled, also read `openxiangda://workspace/appspec` or call `appspec_context`. Require `aiCatalog` and `aiCatalogDigest` to match the normal compiler output. This is a stdio transport mode, not another application-owned server. Never write an application MCP server, Catalog file, preview store or second authorization path.
34
+
35
+ - For an ordinary CRUD module, omit unused backend/platform blocks; the platform owns CRUD. `pnpm dev` uses connected development and starts Nest only when enabled or required by declared server capabilities. Run interface tests for changed business rules and browser tests for the actual PC/mobile create/edit/save/read journeys; passing HTTP tests alone is not acceptance.
36
+
37
+
38
+ ## Standard data entry and list controls
39
+
40
+ Use the platform standard list for nested AND/OR conditions, display-column
41
+ selection/order/freezing and multiple sorting. Set `requiresSelection: true` on
42
+ selection-dependent toolbar contributions. Preserve hidden fields and query /
43
+ export parity. Column changes preview immediately and save to current-user
44
+ platform preferences explicitly.
45
+
46
+ Standard forms use Save draft / Submit. Consume platform authenticated drafts;
47
+ do not create application draft tables, localStorage or Nest draft endpoints.
48
+ PC drawer controls are Full screen / New page / Close, with a platform draft
49
+ handoff to the new page. Mobile entry uses grouped touch-field rows, a simple
50
+ title and a fixed action footer, with bottom sheets for drafts and recovery.
51
+ Do not add a mobile Back to list action or desktop form controls. Preserve edit
52
+ revisions and draft CAS; successful submission consumes the draft atomically.
53
+
54
+ ## Optional application backend
55
+
56
+ The default scaffold contains Web and shared contracts only. Declare
57
+ `backend: { enabled: true }` or application server capabilities, then use the
58
+ existing `pnpm openxiangda check` / `pnpm dev` loop. The tool initializes Nest
59
+ source and its exact dependencies once, preserves authored source, and retries
60
+ an interrupted dependency install. Standard platform workflow activation does
61
+ not imply application Nest. See `docs/backend.md` and the runnable
62
+ `examples/business-action-extension` for SDK ownership and transaction retries.