openxiangda 2.0.0-alpha.2 → 2.0.0-alpha.21

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 (88) hide show
  1. package/bin/run.js +6 -1
  2. package/dist/browser/AuthoritativeSelector.d.ts.map +1 -1
  3. package/dist/browser/AuthoritativeSelector.js +4 -2
  4. package/dist/browser/AuthoritativeSelector.js.map +1 -1
  5. package/dist/browser/Shell.d.ts.map +1 -1
  6. package/dist/browser/Shell.js +213 -56
  7. package/dist/browser/Shell.js.map +1 -1
  8. package/dist/browser/admin-contributions.d.ts +66 -0
  9. package/dist/browser/admin-contributions.d.ts.map +1 -0
  10. package/dist/browser/admin-contributions.js +196 -0
  11. package/dist/browser/admin-contributions.js.map +1 -0
  12. package/dist/browser/application.d.ts +7 -1
  13. package/dist/browser/application.d.ts.map +1 -1
  14. package/dist/browser/application.js +68 -23
  15. package/dist/browser/application.js.map +1 -1
  16. package/dist/browser/components/platform-fields/SubtableField.js +3 -3
  17. package/dist/browser/components/platform-fields/SubtableField.js.map +1 -1
  18. package/dist/browser/components/platform-fields/resource-query.d.ts +0 -1
  19. package/dist/browser/components/platform-fields/resource-query.d.ts.map +1 -1
  20. package/dist/browser/components/platform-fields/resource-query.js +7 -8
  21. package/dist/browser/components/platform-fields/resource-query.js.map +1 -1
  22. package/dist/browser/components/resource/GeneratedResourceCrud.d.ts.map +1 -1
  23. package/dist/browser/components/resource/GeneratedResourceCrud.js +134 -46
  24. package/dist/browser/components/resource/GeneratedResourceCrud.js.map +1 -1
  25. package/dist/browser/components/resource/StandardResourcePages.d.ts +3 -2
  26. package/dist/browser/components/resource/StandardResourcePages.d.ts.map +1 -1
  27. package/dist/browser/components/resource/StandardResourcePages.js +13 -13
  28. package/dist/browser/components/resource/StandardResourcePages.js.map +1 -1
  29. package/dist/browser/components/resource/SurfaceFields.d.ts.map +1 -1
  30. package/dist/browser/components/resource/SurfaceFields.js +6 -2
  31. package/dist/browser/components/resource/SurfaceFields.js.map +1 -1
  32. package/dist/browser/components/workflow/StandardWorkflowPages.d.ts +13 -0
  33. package/dist/browser/components/workflow/StandardWorkflowPages.d.ts.map +1 -0
  34. package/dist/browser/components/workflow/StandardWorkflowPages.js +407 -0
  35. package/dist/browser/components/workflow/StandardWorkflowPages.js.map +1 -0
  36. package/dist/browser/platform-client.d.ts +41 -2
  37. package/dist/browser/platform-client.d.ts.map +1 -1
  38. package/dist/browser/platform-client.js +117 -10
  39. package/dist/browser/platform-client.js.map +1 -1
  40. package/dist/browser/runtime-meta.d.ts +2 -0
  41. package/dist/browser/runtime-meta.d.ts.map +1 -1
  42. package/dist/browser/runtime-meta.js +12 -0
  43. package/dist/browser/runtime-meta.js.map +1 -1
  44. package/dist/browser/runtime.d.ts +8 -1
  45. package/dist/browser/runtime.d.ts.map +1 -1
  46. package/dist/browser/runtime.js +61 -13
  47. package/dist/browser/runtime.js.map +1 -1
  48. package/dist/browser/selector-copy.d.ts +6 -0
  49. package/dist/browser/selector-copy.d.ts.map +1 -0
  50. package/dist/browser/selector-copy.js +13 -0
  51. package/dist/browser/selector-copy.js.map +1 -0
  52. package/dist/browser/styles.css +449 -15
  53. package/dist/browser/workflow-definitions.d.ts +25 -0
  54. package/dist/browser/workflow-definitions.d.ts.map +1 -0
  55. package/dist/browser/workflow-definitions.js +32 -0
  56. package/dist/browser/workflow-definitions.js.map +1 -0
  57. package/dist/config.d.ts +1 -1
  58. package/dist/config.d.ts.map +1 -1
  59. package/dist/config.js +1 -1
  60. package/dist/config.js.map +1 -1
  61. package/dist/internal/web-build-verifier.d.ts +8 -0
  62. package/dist/internal/web-build-verifier.d.ts.map +1 -0
  63. package/dist/internal/web-build-verifier.js +55 -0
  64. package/dist/internal/web-build-verifier.js.map +1 -0
  65. package/dist/nest.d.ts +3 -4
  66. package/dist/nest.d.ts.map +1 -1
  67. package/dist/nest.js +2 -3
  68. package/dist/nest.js.map +1 -1
  69. package/dist/react.d.ts +3 -0
  70. package/dist/react.d.ts.map +1 -1
  71. package/dist/react.js +3 -0
  72. package/dist/react.js.map +1 -1
  73. package/dist/testing.d.ts +1 -0
  74. package/dist/testing.d.ts.map +1 -1
  75. package/dist/testing.js +1 -0
  76. package/dist/testing.js.map +1 -1
  77. package/package.json +7 -7
  78. package/skills/manifest.json +1 -1
  79. package/skills/openxiangda-v2/SKILL.md +18 -14
  80. package/skills/openxiangda-v2/references/appspec.md +67 -0
  81. package/skills/openxiangda-v2/references/backend.md +58 -9
  82. package/skills/openxiangda-v2/references/commands.md +21 -0
  83. package/skills/openxiangda-v2/references/data-authz.md +39 -5
  84. package/skills/openxiangda-v2/references/delivery.md +17 -1
  85. package/skills/openxiangda-v2/references/frontend.md +47 -1
  86. package/skills/openxiangda-v2/references/testing.md +46 -2
  87. package/skills/openxiangda-v2/references/{workflow-notification.md → workflow-events.md} +6 -3
  88. package/skills/openxiangda-v2/references/workspace.md +9 -5
@@ -1,5 +1,8 @@
1
1
  # OpenXiangda 2.0 Frontend
2
2
 
3
+ Read [Data and authorization](data-authz.md) for every resource or permission
4
+ change and keep the generated [workspace contract](workspace.md) authoritative.
5
+
3
6
  Use the official Vite + React Router + Refine Core + Ant Design template. Import the platform-owned runtime from `openxiangda/react`, field controls from `openxiangda/field-kit` and clients/types from `openxiangda/core`. Do not copy these implementations into application source and do not add per-resource function wrappers.
4
7
 
5
8
  Generated desktop lists already own row selection, atomic batch update/delete,
@@ -7,4 +10,47 @@ CSV/XLS/XLSX preview import, export, filters, column settings and density. Keep
7
10
  imports at 100 rows per transaction, use exact declared labels or field codes,
8
11
  and leave attachment values to the platform managed-file component.
9
12
 
10
- Read the current user, complete application-role union and capabilities from the platform runtime authorization endpoint. There is no role switcher and the browser does not send a RoleSession header. Use capabilities and field access only to present or disable UI; strip unauthorized fields from create and update payloads and never treat a disabled input as server authorization. Verify with `pnpm openxiangda check`.
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.
20
+
21
+ 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
+
23
+ Use the standard `Shell` unchanged. It owns the authenticated user's display
24
+ name, account identifier, safe avatar upload, localized application-role names,
25
+ theme controls, Perspective selection and navigation scroll restoration. It
26
+ also owns directory field requests under the current logged-in user's role
27
+ union. Never fetch identity for the header, display role codes, add a second
28
+ identity selector, or copy Shell and
29
+ directory-client implementations into application source.
30
+
31
+ For a custom admin operation page, declare the route in
32
+ `openxiangda.config.ts`, import the generated `appRoutes`, and bind every route
33
+ key to exactly one local React page with `defineAdminContributions` from
34
+ `openxiangda/react`. Pass the result to `OpenXiangdaApplication`. Do not wrap the
35
+ page in another `Shell`: the runtime registers it in the unified router and the
36
+ same Shell owns its menu entry, title, history and direct-URL capability gate.
37
+ Only `navigation: 'menu'` routes enter the menu; hidden routes retain the same
38
+ `capability` or `access.allOf/anyOf`, including ancestor constraints. Never add
39
+ an application-owned layout, router, menu, identity provider or permission
40
+ store. Keep operation pages under `/admin/operations`; parameterized routes are
41
+ hidden so they cannot become unresolved menu links.
42
+
43
+ For a small business action on a generated resource page, use the typed
44
+ `resources[resourceCode].toolbar`, `.row` or `.detail` slots accepted by
45
+ `defineAdminContributions`. Declare a stable action code, label and
46
+ capability/access expression. The render context contains only the current
47
+ resource, already-authorized record or selection, and a bounded `refresh()`;
48
+ it does not own CRUD, revisions, fields or authorization. Invoke a guarded Nest
49
+ App Operation for cross-resource transactions, invariants or side effects and
50
+ leave ordinary CRUD on the Native Data API. Do not copy a generated page just
51
+ to insert a button.
52
+
53
+ Generated contracts intentionally emit each resource Surface once in
54
+ `resourceSurfaces`; `resourceDefinitions[code].surface` references that shared
55
+ object. Import the generated runtime definitions normally. Do not serialize,
56
+ inline or duplicate Surface literals in application code.
@@ -1,6 +1,14 @@
1
1
  # Testing and Acceptance
2
2
 
3
- Run `pnpm openxiangda check` after declaration or code changes. It owns generation, static validation, unit tests and production builds; preserve its stable diagnostic instead of bypassing a failing stage.
3
+ Run `pnpm openxiangda check --json` after declaration or code changes. It owns
4
+ generation, static validation, unit tests and production builds; preserve its
5
+ stable diagnostic instead of bypassing a failing stage. Read
6
+ `data.sealedArtifact` in the machine result. A successful check always reports
7
+ `state: "check-did-not-seal"`, `sealed: false` and
8
+ `usableForDeploy: false`; it may also describe an older package as
9
+ `previousArtifact`. Never treat an existing `.openxiangda/build/app-package.json`
10
+ as output from the current check. Follow the exact `nextCommand`: rerun check
11
+ when diagnostics fail, or run `openxiangda deploy` to build, seal and deploy.
4
12
 
5
13
  For each changed resource, verify the real chain:
6
14
 
@@ -11,6 +19,42 @@ For each changed resource, verify the real chain:
11
19
  5. stored values and audit records match the declared shape;
12
20
  6. PostgreSQL/RLS remains authoritative, including current-user and multi-role-union cases.
13
21
 
14
- Mock and unit tests are useful but do not close remote acceptance. Before production, deploy to preproduction and capture the exact AppVersion, environment Head, test identities, positive/negative results, browser behavior and request identifiers. Production promotion reuses that exact successful version; it is not another build.
22
+ For platform generator changes, add a representative multi-resource fixture
23
+ (currently nineteen standard resources), assert each Surface literal is emitted
24
+ only once, then run the unchanged Web dist budget gate. A budget failure is a
25
+ generator/runtime regression to fix; never raise the application budget or copy
26
+ generated contracts into a smaller application-local format. Browser acceptance
27
+ must also cover the large more-filters modal, declaration-order forms, hidden
28
+ developer-only authorization copy, real account/role labels, avatar update and
29
+ left-menu scroll preservation across route changes.
30
+
31
+ Mock and unit tests are useful but do not close remote acceptance. When real
32
+ identity acceptance is needed, create a short-lived local plan and run:
33
+
34
+ ```bash
35
+ pnpm openxiangda accept --plan .openxiangda/acceptance-plan.json --json
36
+ ```
37
+
38
+ The plan is explicit and preproduction-only:
39
+
40
+ ```json
41
+ {
42
+ "schemaVersion": "openxiangda.preproduction-acceptance-plan/v2",
43
+ "environmentKey": "preproduction",
44
+ "expiresInMinutes": 240,
45
+ "actors": [
46
+ { "key": "allowed", "roleCodes": ["resource_admin"] },
47
+ { "key": "denied", "roleCodes": ["resource_viewer"] }
48
+ ]
49
+ }
50
+ ```
51
+
52
+ The result returns real temporary users and one-time login URLs. Treat those
53
+ URLs as secrets, do not commit the plan/result, and let them expire. `accept`
54
+ is an additional manual test facility: it is never called by `check` or
55
+ `deploy`, never becomes a release gate, and a skipped run must not block a
56
+ release. When it is used, capture the exact AppVersion, environment Head,
57
+ positive/negative result, browser behavior and request identifiers. Production
58
+ promotion reuses the exact successful version; it is not another build.
15
59
 
16
60
  For a new toolchain release, also create a completely fresh workspace using only the packed or published `openxiangda` package. Do not use repository-relative imports, unpublished workspace links or machine-installed legacy Skills.
@@ -1,4 +1,7 @@
1
- # Workflow and Notification Hub
1
+ # Workflow, Events and Notification Hub
2
+
3
+ Read [Architecture](architecture.md), [Data and authorization](data-authz.md)
4
+ and [Testing](testing.md) before enabling this optional layer.
2
5
 
3
6
  Use these optional modules only when the application has a real standard approval or cross-channel notification requirement. Ordinary CRUD and application-specific state machines stay on Data API/App API and must not pull Workflow or Notification code into the default template.
4
7
 
@@ -8,7 +11,7 @@ Use these optional modules only when the application has a real standard approva
8
11
  - Workflow Kernel v2 owns definitions, instances, tasks, participants, commands, transitions and audit facts.
9
12
  - Application Events v2 owns durable facts and delivery.
10
13
  - Notification Hub v2 owns templates, rules, logical messages, channel delivery, callbacks and message operations.
11
- - Native Identity/AuthZ v2 owns the current user and the union of that user's current application roles. Never select, transmit or persist a RoleSession.
14
+ - Native Identity/AuthZ v2 owns the current user and the union of that user's current application roles. Perspective is read-only and never changes workflow participation or action authorization.
12
15
  - Never import, query, migrate or call 1.x workflow/message code, tables, APIs, queues, templates or callbacks.
13
16
 
14
17
  ## Workflow declaration
@@ -46,7 +49,7 @@ Template variables must be declared by JSON Schema and stay within the field pol
46
49
 
47
50
  ## Detail navigation
48
51
 
49
- Use a canonical navigation target with `PLATFORM_ROUTE`, `APP_ROUTE` or allowlisted `EXTERNAL_URL`, stable route code, path/query parameters and an authenticated access requirement. Do not place environment domains, bearer tokens, cookies, RoleSession identifiers or secrets in template strings.
52
+ Use a canonical navigation target with `PLATFORM_ROUTE`, `APP_ROUTE` or allowlisted `EXTERNAL_URL`, stable route code, path/query parameters and an authenticated access requirement. Do not place environment domains, bearer tokens, cookies, identity-switching credentials or secrets in template strings.
50
53
 
51
54
  The Notification Hub resolves desktop, mobile and channel deep links. The landing page always re-runs platform authentication and Data/AuthZ/Workflow authorization.
52
55
 
@@ -1,21 +1,25 @@
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.
4
5
  - Use Vite, React Router, Refine Core and Ant Design. Do not add Umi, ProComponents or another admin shell.
6
+ - Keep generated admin routes and custom actions inside the platform Shell. Bind generated `appRoutes` to local operation pages with `defineAdminContributions`, and use only its typed `toolbar`, `row` and `detail` resource slots. Do not create another router, menu, layout, identity provider, permission store or copied CRUD page; route/action access uses capability or `allOf`/`anyOf`, while Data/App API authorization remains server-owned.
5
7
  - Declare each resource once in `openxiangda.config.ts` with only `code`, `name`, `fields` and optional list/layout/data-policy settings. Each field owns type, label, required state, Surface flags, reference/file metadata and access. Resource codes are lower kebab-case.
6
8
  - 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`.
7
9
  - 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.
8
10
  - Add NestJS only for a named business action that needs a cross-resource transaction, an invariant or an external side effect.
11
+ - Every interactive business action binds `@OpenXiangdaOperation(operation)` and injects `OpenXiangdaBusinessDataApiService` or `OpenXiangdaStandardOperations`. The platform checks the action capability once at App API ingress; the trusted backend then has full Data access only to its exact application/environment while audit retains the initiating user. Do not author `authorizationJSON` or reapply the user's resource, row and field permissions inside the action.
9
12
  - 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.
10
- - Use the current logged-in user and the union of that user's application roles. The generated client uses same-origin cookies and does not transmit a RoleSession header. Business code must not persist a platform Token or authorization result and must not implement a second identity path.
13
+ - Use the current logged-in user and the union of that user's application roles. 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.
11
14
  - Fields inherit the resource read/create/update capabilities. Use field `access` only to tighten them; arrays are all-of and `false` is explicit deny. There is no `write` fallback.
12
15
  - Field `type` is semantic, never a hand-authored database type. The supported catalog is exactly `text.short`, `text.long`, `text.rich`, `number.integer`, `number.decimal`, `boolean`, `date`, `time`, `datetime`, `date-range`, `datetime-range`, `option.single`, `option.multiple`, `cascade.single`, `cascade.multiple`, `user.single`, `user.multiple`, `department.single`, `department.multiple`, `resource-ref.single`, `resource-ref.multiple`, `file`, `image`, `signature`, `address`, `location`, `json`, `serial-number`, `uuid` and `subtable`. The compiler alone derives PostgreSQL columns, constraints and indexes.
13
16
  - Declare every custom operation capability in `authz.capabilities` with `kind: 'backend'`, then reference that same code from the operation and its allowed roles. Generated resource CRUD capabilities do not go in this catalog.
17
+ - Build App Operation request/response schemas with `resourceRecordSchema`, `schemaRef`, `composeJsonSchema` and `composeAppOperationSchemas` from `openxiangda/config`. They project the same Resource declaration and canonical field value protocols; never import a physical toolchain package or repeat user, department, resource-reference or managed-file schemas by hand.
14
18
  - 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.
15
- - Desktop and mobile pages share values, validation and authorization, but use separate renderers. Options, members, departments and resource references store their complete display snapshots; attachments, images and signatures use platform-managed file references.
16
- - `option.*`, `user.*`, `department.*` and `resource-ref.*` values never collapse to scalar IDs. Single values store one labeled snapshot and multiple values store snapshot arrays. `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`.
19
+ - 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.
20
+ - `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`.
17
21
  - Derive role grants with `resourceCapabilityCodes(appCode, resourceCode)`. Declare current-user rows only with `currentUserDataPolicy(...)`; do not invent operators, values or alternate current-user spellings.
18
22
  - 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.
19
23
  - Standard Workflow and Notification Hub are optional 2.0 modules. Enable them only through the canonical `openxiangda.config.ts` declarations and generated clients; never copy 1.x workflow/message code, tables, APIs, templates or callbacks into this workspace. Keep ordinary CRUD and application-specific state machines independent of them.
20
- - Run `pnpm openxiangda check` after contract changes. 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.
21
- - 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`, and require its `aiCatalog` and `aiCatalogDigest` to match the normal compiler output. This is a stdio transport mode, not a ninth CLI command. Never write an application MCP server, Catalog file, preview store or second authorization path.
24
+ - 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.
25
+ - 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`; 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.