openxiangda-cli 2.0.0-alpha.68 → 2.0.0-alpha.69

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-cli",
3
- "version": "2.0.0-alpha.68",
3
+ "version": "2.0.0-alpha.69",
4
4
  "description": "Thin application-level CLI for OpenXiangda 2.0.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -23,9 +23,9 @@
23
23
  ],
24
24
  "dependencies": {
25
25
  "@oclif/core": "4.13.3",
26
- "openxiangda-contracts": "2.0.0-alpha.31",
27
- "openxiangda-devkit-core": "2.0.0-alpha.41",
28
- "openxiangda-mcp": "2.0.0-alpha.41"
26
+ "openxiangda-contracts": "2.0.0-alpha.32",
27
+ "openxiangda-devkit-core": "2.0.0-alpha.42",
28
+ "openxiangda-mcp": "2.0.0-alpha.42"
29
29
  },
30
30
  "devDependencies": {
31
31
  "tsx": "4.23.12",
@@ -1,8 +1,13 @@
1
- # Application development rules
1
+ # OpenXiangda 2.0 Application Agent Contract
2
2
 
3
- - Build normal application code directly; generated Skills and historical templates are not design authority.
4
- - Keep CRUD in the replaceable browser Data API adapter under `/service`.
5
- - Put only real transactional or integration actions in Nest under `/api`.
6
- - Read current-user role/capability unions from the platform. UI guards are presentation only; server authorization is authoritative.
7
- - Use the declared `reference` mapping for members, departments, and related resources; persist stable IDs, not display labels.
8
- - Run `openxiangda check` before delivery.
3
+ - Use only the workspace-pinned CLI: `pnpm openxiangda <command>`. Never invoke a bare global `openxiangda` inside a 2.0 task.
4
+ - Use Vite, React Router, Refine Core and Ant Design. Do not add Umi, ProComponents or another admin shell.
5
+ - Declare each resource once in `openxiangda.config.ts`. Resource codes are lower kebab-case. The same declaration owns storage, Surface metadata, permissions and generated AI Schema.
6
+ - 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.
7
+ - Add NestJS only for a named business action that needs a cross-resource transaction, an invariant or an external side effect.
8
+ - 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.
9
+ - Use the current logged-in user and the union of application roles. Do not select RoleSession, persist platform Token or implement a second authorization path.
10
+ - Declare restricted field read, create and update permissions explicitly. There is no `write` fallback; generated update permission is denied unless explicitly granted.
11
+ - Desktop and mobile pages share values, validation and authorization, but use separate renderers. Members, departments, resources and attachments use platform-owned selectors and stable IDs.
12
+ - 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.
13
+ - 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.
@@ -3,10 +3,10 @@
3
3
  这是干净的资源 CRUD 模板:Vite + React Router + Refine Core + Ant Design 前端、NestJS 平台启动层,以及平台 Data/AuthZ 声明。
4
4
 
5
5
  ```bash
6
- openxiangda login --base-url https://platform.example.com
7
- openxiangda create visitor-reservations
6
+ pnpm dlx openxiangda-cli@latest login --base-url https://platform.example.com
7
+ pnpm dlx openxiangda-cli@latest create visitor-reservations
8
8
  cd visitor-reservations
9
- openxiangda dev
9
+ pnpm openxiangda dev
10
10
  ```
11
11
 
12
12
  在 `platform/data` 中声明 `DataResource` 和字段即可生成标准后台列表、筛选、表单、详情、审计、文件上传和独立移动端页面。成员、部门和资源关系分别使用 `reference: { kind: 'directory-user' }`、`directory-department`、`resource`,只保存稳定 ID,不复制目录数据。
@@ -16,10 +16,10 @@ openxiangda dev
16
16
  前端读取平台 current-user 的角色/能力并集进行展示保护,服务端始终权威。字段策略区分 create/update;无权字段在提交前从 payload 删除。
17
17
 
18
18
  ```bash
19
- openxiangda check
20
- openxiangda deploy
21
- openxiangda status
22
- openxiangda logs
19
+ pnpm openxiangda check
20
+ pnpm openxiangda deploy
21
+ pnpm openxiangda status
22
+ pnpm openxiangda logs
23
23
  ```
24
24
 
25
25
  `deploy` 使用本模板的 `apps/server/Dockerfile` 自动构建并推送 `linux/amd64` 镜像,再把不可变 digest 写入 AppPackage。纯 CRUD 应用可以保持 backend disabled;复杂事务再启用 Nest。
@@ -15,7 +15,7 @@
15
15
  "@nestjs/common": "11.1.29",
16
16
  "@nestjs/core": "11.1.29",
17
17
  "@nestjs/platform-fastify": "11.1.29",
18
- "openxiangda-nest": "2.0.0-alpha.37",
18
+ "openxiangda-nest": "2.0.0-alpha.38",
19
19
  "reflect-metadata": "0.2.2",
20
20
  "rxjs": "7.8.2"
21
21
  },
@@ -16,7 +16,7 @@
16
16
  "antd": "6.4.3",
17
17
  "dayjs": "1.11.18",
18
18
  "docx-preview": "0.3.7",
19
- "openxiangda-contracts": "2.0.0-alpha.31",
19
+ "openxiangda-contracts": "2.0.0-alpha.32",
20
20
  "react": "19.2.8",
21
21
  "react-dom": "19.2.8",
22
22
  "react-router-dom": "7.8.2",
@@ -6,26 +6,31 @@ const files = [];
6
6
  function visit(directory) {
7
7
  for (const entry of readdirSync(directory, { withFileTypes: true })) {
8
8
  const path = join(directory, entry.name);
9
- if (
10
- entry.isDirectory() &&
11
- !['.umi', '.umi-production', '.turbopack'].includes(entry.name)
12
- )
13
- visit(path);
9
+ if (entry.isDirectory() && !['.umi', '.umi-production', '.turbopack'].includes(entry.name)) visit(path);
14
10
  else if (/\.(?:ts|tsx)$/.test(entry.name)) files.push(path);
15
11
  }
16
12
  }
17
13
  visit(join(root, 'src'));
18
- const lines = files.reduce(
19
- (total, file) => total + readFileSync(file, 'utf8').split(/\r?\n/).length,
20
- 0
21
- );
14
+ const lines = files.reduce((total, file) => total + readFileSync(file, 'utf8').split(/\r?\n/).length, 0);
22
15
  // The shared Surface renderer is deliberately counted as application source;
23
16
  // keep its small budget explicit instead of hiding it in generated output.
24
17
  if (files.length > 20) throw new Error(`WEB_SOURCE_FILE_BUDGET_EXCEEDED:${files.length}>20`);
25
- // Mobile shells, Surface filters, and generated resource CRUD are shared application infrastructure.
26
- if (lines > 5_600) throw new Error(`WEB_BUSINESS_LOC_BUDGET_EXCEEDED:${lines}>5600`);
27
- const source = files.map(file => readFileSync(file, 'utf8')).join('\n');
28
- for (const marker of ['@umijs/', 'openxiangda-' + 'admin', 'openxiangda-' + 'user', 'instrument_query', 'instrument_save', 'function.invoke', 'role' + '-session', 'college-' + 'am', 'user-' + 'wang', 'dept-' + 'am-test']) {
18
+ // Mobile shells, Surface filters, generated resource CRUD, atomic batch actions,
19
+ // and import preview are shared application infrastructure.
20
+ if (lines > 6_000) throw new Error(`WEB_BUSINESS_LOC_BUDGET_EXCEEDED:${lines}>6000`);
21
+ const source = files.map((file) => readFileSync(file, 'utf8')).join('\n');
22
+ for (const marker of [
23
+ '@umijs/',
24
+ 'openxiangda-' + 'admin',
25
+ 'openxiangda-' + 'user',
26
+ 'instrument_query',
27
+ 'instrument_save',
28
+ 'function.invoke',
29
+ 'role' + '-session',
30
+ 'college-' + 'am',
31
+ 'user-' + 'wang',
32
+ 'dept-' + 'am-test',
33
+ ]) {
29
34
  if (source.includes(marker)) throw new Error(`WEB_FORBIDDEN_MARKER:${marker}`);
30
35
  }
31
36
  const playwright = readFileSync(join(root, 'playwright.config.ts'), 'utf8');