cabloy 5.1.149 → 5.1.151

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 (122) hide show
  1. package/.cabloy-version +1 -1
  2. package/.claude/commands/release.md +12 -1
  3. package/.claude/hooks/contract-loop-gate.ts +35 -17
  4. package/.claude/skills/cabloy-backend-scaffold/SKILL.md +4 -3
  5. package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +3 -2
  6. package/.claude/skills/cabloy-contract-loop/SKILL.md +4 -3
  7. package/.claude/skills/cabloy-domain-planning/SKILL.md +4 -3
  8. package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +5 -3
  9. package/.claude/skills/cabloy-master-detail/SKILL.md +4 -3
  10. package/.claude/skills/cabloy-module-removal/SKILL.md +5 -4
  11. package/.claude/skills/cabloy-resource-field-update/SKILL.md +8 -5
  12. package/.claude/skills/cabloy-spec-execution/SKILL.md +169 -0
  13. package/.claude/skills/cabloy-spec-execution/evals/evals.json +71 -0
  14. package/.claude/skills/cabloy-spec-execution/references/execution-protocol.md +137 -0
  15. package/.claude/skills/cabloy-spec-execution/references/status-and-evidence.md +117 -0
  16. package/.claude/skills/cabloy-spec-generation/SKILL.md +227 -0
  17. package/.claude/skills/cabloy-spec-generation/evals/evals.json +83 -0
  18. package/.claude/skills/cabloy-spec-generation/references/repo-aware-discovery.md +101 -0
  19. package/.claude/skills/cabloy-spec-generation/references/repo-specs-document-set.md +267 -0
  20. package/.claude/skills/cabloy-spec-generation/references/traceability-and-status-rules.md +135 -0
  21. package/.claude/skills/cabloy-spec-generation/scripts/generate-implementation-charts.mjs +350 -0
  22. package/.claude/skills/cabloy-spec-generation/scripts/generate-implementation-charts.test.mjs +202 -0
  23. package/.claude/skills/cabloy-workflow/SKILL.md +21 -10
  24. package/.claude/skills/cabloy-workflow/evals/evals.json +8 -2
  25. package/.claude/skills/cabloy-workflow/references/edition-detection.md +5 -3
  26. package/.claude/skills/cabloy-zova-source-reading/SKILL.md +4 -3
  27. package/CHANGELOG.md +41 -0
  28. package/CLAUDE.md +12 -11
  29. package/package.json +4 -2
  30. package/repo-docs/.vitepress/config.mjs +4 -0
  31. package/repo-docs/ai/docs-skills-rules-mapping.md +6 -6
  32. package/repo-docs/ai/future-skill-roadmap.md +2 -2
  33. package/repo-docs/ai/introduction.md +5 -5
  34. package/repo-docs/ai/playbook-contract-regeneration.md +3 -9
  35. package/repo-docs/ai/repo-guidance.md +5 -4
  36. package/repo-docs/ai/rules-and-config.md +2 -2
  37. package/repo-docs/ai/virtual-decorator-guidance.md +1 -3
  38. package/repo-docs/backend/cache-guide.md +36 -0
  39. package/repo-docs/backend/dto-guide.md +7 -6
  40. package/repo-docs/backend/dto-infer-generation.md +25 -5
  41. package/repo-docs/backend/introduction.md +1 -1
  42. package/repo-docs/backend/migration-and-changes.md +27 -2
  43. package/repo-docs/backend/model-guide.md +1 -1
  44. package/repo-docs/backend/resource-field-update.md +156 -0
  45. package/repo-docs/frontend/a-model-under-the-hood.md +38 -0
  46. package/repo-docs/frontend/a-openapi-under-the-hood.md +13 -2
  47. package/repo-docs/frontend/form-layout-guide.md +26 -9
  48. package/repo-docs/frontend/model-resource-best-practices.md +2 -0
  49. package/repo-docs/frontend/model-resource-cookbook.md +7 -1
  50. package/repo-docs/frontend/router-tabs-introduction.md +2 -4
  51. package/repo-docs/frontend/use-state-data-best-practices.md +44 -0
  52. package/repo-docs/frontend/zova-form-source-reading-map.md +26 -9
  53. package/repo-docs/frontend/zova-form-under-the-hood.md +11 -0
  54. package/repo-docs/fullstack/a-pay-payment-suite.md +1 -1
  55. package/repo-docs/fullstack/contract-loop-playbook.md +4 -0
  56. package/repo-docs/fullstack/one-to-one-companion-resource-guide.md +2 -2
  57. package/repo-docs/reference/package-map.md +1 -1
  58. package/repo-e2e/specs/a-commerce.spec.ts +40 -0
  59. package/scripts/release.ts +48 -1
  60. package/scripts/upgrade.ts +18 -7
  61. package/vona/packages-cli/cli/package.json +1 -1
  62. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudStart/boilerplate/src/controller/{{resourceName}}.ts_ +2 -2
  63. package/vona/packages-cli/cli-set-api/package.json +1 -1
  64. package/vona/pnpm-lock.yaml +83 -75
  65. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/index.ts +108 -108
  66. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuSelectResItem.tsx +12 -0
  67. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/service/sku.ts +19 -1
  68. package/vona/src/suite/a-commerce/modules/commerce-catalog/test/skuPresentation.test.ts +53 -4
  69. package/vona/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +148 -148
  70. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAdjust.tsx +37 -3
  71. package/vona/src/suite/a-training/modules/training-student/src/.metadata/index.ts +2 -2
  72. package/vona/src/suite/a-training/modules/training-student/src/dto/studentCreate.tsx +7 -6
  73. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSummary.tsx +1 -1
  74. package/vona/src/suite/a-training/modules/training-student/src/dto/studentUpdate.tsx +7 -6
  75. package/vona/src/suite/a-training/modules/training-student/src/dto/studentView.tsx +10 -7
  76. package/vona/src/suite/a-training/modules/training-student/src/model/student.ts +4 -4
  77. package/vona/src/suite/a-training/modules/training-student/src/service/student.ts +39 -67
  78. package/vona/src/suite/a-training/modules/training-student/test/student.test.ts +56 -37
  79. package/zova/packages-zova/zova/package.json +2 -2
  80. package/zova/pnpm-lock.yaml +5 -5
  81. package/zova/src/suite/a-commerce/modules/commerce-trade/cli/openapi.config.ts +1 -0
  82. package/zova/src/suite/a-commerce/modules/commerce-trade/package.json +6 -1
  83. package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/component/tableCellActionAdjustStock.ts +34 -0
  84. package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +81 -6
  85. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/commerceTradeStockBalance.ts +32 -0
  86. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/schemas.ts +44 -44
  87. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/types.ts +356 -338
  88. package/zova/src/suite/a-commerce/modules/commerce-trade/src/apiSchema/commerceTradeStockBalance.ts +17 -0
  89. package/zova/src/suite/a-commerce/modules/commerce-trade/src/bean/tableCell.actionAdjustStock.tsx +35 -0
  90. package/zova/src/suite/a-commerce/modules/commerce-trade/src/component/tableCellActionAdjustStock/controller.tsx +138 -0
  91. package/zova/src/suite/a-commerce/modules/commerce-trade/src/config/locale/en-us.ts +3 -0
  92. package/zova/src/suite/a-commerce/modules/commerce-trade/src/config/locale/zh-cn.ts +3 -0
  93. package/zova/src/suite/a-commerce/modules/commerce-trade/src/model/stockBalance.ts +36 -0
  94. package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/payment/controller.tsx +4 -4
  95. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/schemas.ts +8 -8
  96. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/types.ts +11 -11
  97. package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.actionSummary.tsx +2 -2
  98. package/zova/src/suite/cabloy-basic/modules/basic-app/src/bean/behavior.appModal.tsx +2 -0
  99. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
  100. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +2 -1
  101. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/test/model/resource.types.ts +11 -0
  102. package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
  103. package/zova/src/suite-vendor/a-zova/modules/a-form/package.json +1 -1
  104. package/zova/src/suite-vendor/a-zova/modules/a-form/src/lib/formLayout.ts +58 -9
  105. package/zova/src/suite-vendor/a-zova/modules/a-form/test/lib/formLayout.test.ts +157 -0
  106. package/zova/src/suite-vendor/a-zova/modules/a-model/package.json +1 -1
  107. package/zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.persister.ts +3 -1
  108. package/zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.useQuery.ts +11 -13
  109. package/zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.useState.ts +9 -7
  110. package/zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.useStateGeneral.ts +5 -12
  111. package/zova/src/suite-vendor/a-zova/modules/a-model/src/lib/queryPersister.ts +17 -0
  112. package/zova/src/suite-vendor/a-zova/modules/a-model/src/lib/queryRefetch.ts +34 -0
  113. package/zova/src/suite-vendor/a-zova/modules/a-model/src/types/query.ts +27 -3
  114. package/zova/src/suite-vendor/a-zova/modules/a-model/test/lib/queryPersister.test.ts +115 -0
  115. package/zova/src/suite-vendor/a-zova/modules/a-model/test/lib/queryRefetch.test.ts +84 -0
  116. package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +1 -1
  117. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/lib/schema.ts +27 -5
  118. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/model/sdk.ts +2 -2
  119. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/rest.ts +4 -0
  120. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/schema.ts +2 -5
  121. package/zova/src/suite-vendor/a-zova/modules/a-openapi/test/lib/schema.test.ts +179 -0
  122. package/zova/src/suite-vendor/a-zova/package.json +4 -4
@@ -21,7 +21,7 @@ export function loadSchemaProperties(
21
21
  schema: SchemaObject | undefined,
22
22
  onGetSchema: (schemaName: string) => SchemaObject | undefined,
23
23
  schemaScene?: TypeSchemaScene,
24
- ): SchemaObject[] | undefined {
24
+ ): ISchemaObjectExtensionField[] | undefined {
25
25
  if (!schema) return;
26
26
  const properties = schema.properties!;
27
27
  const result: ISchemaObjectExtensionField[] = [];
@@ -32,12 +32,26 @@ export function loadSchemaProperties(
32
32
  property = onGetSchema(property.$ref)!;
33
33
  }
34
34
  if (!property) continue;
35
- const fieldSource = property.rest?.fieldSource;
35
+ const schemaKey = key;
36
+ const propertyRest = deepExtend(
37
+ {},
38
+ property.rest,
39
+ schemaScene && ['form-view', 'form-create', 'filter'].includes(schemaScene)
40
+ ? property.rest?.form
41
+ : undefined,
42
+ schemaScene ? property.rest?.[schemaScene] : undefined,
43
+ );
44
+ const fieldSource = propertyRest?.fieldSource;
36
45
  if (fieldSource) {
37
46
  const parts = fieldSource.split('.');
38
- const propertyParent: any =
39
- parts[0] === key ? property : result.find(item => item.key === parts[0]);
40
- property = propertyParent?.properties[parts[1]];
47
+ let propertyParent =
48
+ parts[0] === schemaKey
49
+ ? property
50
+ : (properties[parts[0]] as ISchemaObjectExtensionField | undefined);
51
+ if (propertyParent?.$ref) {
52
+ propertyParent = onGetSchema(propertyParent.$ref)!;
53
+ }
54
+ property = propertyParent?.properties?.[parts[1]] as ISchemaObjectExtensionField;
41
55
  key = fieldSource;
42
56
  }
43
57
  if (!property) continue;
@@ -49,6 +63,14 @@ export function loadSchemaProperties(
49
63
  : undefined,
50
64
  schemaScene ? { rest: property.rest?.[schemaScene] ?? {} } : undefined,
51
65
  );
66
+ if (schemaKey !== key) {
67
+ property.schemaKey = schemaKey;
68
+ }
69
+ const propertyExisting = result.find(item => item.key === key);
70
+ if (propertyExisting) {
71
+ propertyExisting.schemaKeys = [...(propertyExisting.schemaKeys ?? []), schemaKey];
72
+ continue;
73
+ }
52
74
  result.push(property);
53
75
  }
54
76
  // sort
@@ -20,7 +20,7 @@ import {
20
20
  schemaToZodSchema,
21
21
  } from '../lib/schema.js';
22
22
  import { TypeOpenapiPermissions } from '../types/permissions.js';
23
- import { TypeSchemaScene } from '../types/rest.js';
23
+ import { ISchemaObjectExtensionField, TypeSchemaScene } from '../types/rest.js';
24
24
  import { IOpenapiSchemas, TypeOpenapiSchemasSdk } from '../types/schema.js';
25
25
  import { TypeRequestMethod } from '../types/sdk.js';
26
26
 
@@ -236,7 +236,7 @@ export class ModelSdk extends BeanModelBase {
236
236
  public loadSchemaProperties(
237
237
  schema: SchemaObject | undefined,
238
238
  schemaScene?: TypeSchemaScene,
239
- ): SchemaObject[] | undefined {
239
+ ): ISchemaObjectExtensionField[] | undefined {
240
240
  return loadSchemaProperties(schema, schemaName => this.getSchema(schemaName).data, schemaScene);
241
241
  }
242
242
 
@@ -47,6 +47,10 @@ export interface ISchemaObjectExtensionFieldFilter {
47
47
 
48
48
  export interface ISchemaObjectExtensionField extends SchemaObject {
49
49
  key?: string;
50
+ /** Original property name before fieldSource normalization. */
51
+ schemaKey?: string;
52
+ /** Additional schema aliases that resolve to this canonical key. */
53
+ schemaKeys?: string[];
50
54
  rest?: ISchemaObjectExtensionFieldRest;
51
55
  filter?: ISchemaObjectExtensionFieldFilter;
52
56
  }
@@ -1,6 +1,5 @@
1
- import type { DefaultError, UseQueryReturnType } from '@tanstack/vue-query';
2
1
  import type { OpenAPIObject, SchemaObject } from 'openapi3-ts/oas31';
3
- import type { UnwrapNestedRefs } from 'vue';
2
+ import type { ModelUseQueryReturnType } from 'zova-module-a-model';
4
3
 
5
4
  import type { IOpenapiSdkItem } from './sdk.js';
6
5
 
@@ -11,9 +10,7 @@ export interface IOpenapiSchema {
11
10
 
12
11
  export interface IOpenapiSchemaMeta {}
13
12
 
14
- export type TypeOpenapiSchemasSdk = UnwrapNestedRefs<
15
- UseQueryReturnType<IOpenapiSdkItem, DefaultError>
16
- >;
13
+ export type TypeOpenapiSchemasSdk = ModelUseQueryReturnType<IOpenapiSdkItem, Error>;
17
14
 
18
15
  export interface IOpenapiSchemas {
19
16
  sdk: TypeOpenapiSchemasSdk;
@@ -0,0 +1,179 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+
4
+ import type { ISchemaObjectExtensionField } from '../../src/types/rest.js';
5
+
6
+ import { loadSchemaProperties } from '../../src/lib/schema.js';
7
+
8
+ const onGetSchema = () => undefined;
9
+
10
+ function field(field: ISchemaObjectExtensionField) {
11
+ return field;
12
+ }
13
+
14
+ test('schema properties preserve the canonical fieldSource key and original schema key', () => {
15
+ const properties = loadSchemaProperties(
16
+ {
17
+ type: 'object',
18
+ properties: {
19
+ content: field({
20
+ type: 'object',
21
+ rest: { fieldSource: 'content.descriptionMarkdown' },
22
+ properties: {
23
+ descriptionMarkdown: field({
24
+ type: 'string',
25
+ rest: { render: 'start-markdown:formFieldMarkdown' as any },
26
+ }),
27
+ },
28
+ }),
29
+ },
30
+ },
31
+ onGetSchema,
32
+ );
33
+
34
+ assert.deepEqual(properties, [
35
+ {
36
+ key: 'content.descriptionMarkdown',
37
+ schemaKey: 'content',
38
+ type: 'string',
39
+ rest: { render: 'start-markdown:formFieldMarkdown' },
40
+ },
41
+ ]);
42
+ });
43
+
44
+ test('schema properties preserve virtual aliases without changing the form key', () => {
45
+ const properties = loadSchemaProperties(
46
+ {
47
+ type: 'object',
48
+ properties: {
49
+ content: field({
50
+ type: 'object',
51
+ rest: { visible: false },
52
+ properties: {
53
+ descriptionMarkdown: field({ type: 'string' }),
54
+ },
55
+ }),
56
+ _descriptionMarkdown: field({
57
+ type: 'object',
58
+ rest: { fieldSource: 'content.descriptionMarkdown' },
59
+ }),
60
+ },
61
+ },
62
+ onGetSchema,
63
+ );
64
+
65
+ assert.deepEqual(properties?.[1], {
66
+ key: 'content.descriptionMarkdown',
67
+ schemaKey: '_descriptionMarkdown',
68
+ type: 'string',
69
+ });
70
+ });
71
+
72
+ test('schema properties normalize a scene-specific fieldSource', () => {
73
+ const properties = loadSchemaProperties(
74
+ {
75
+ type: 'object',
76
+ properties: {
77
+ content: field({
78
+ type: 'object',
79
+ rest: { visible: false },
80
+ properties: {
81
+ descriptionMarkdown: field({ type: 'string' }),
82
+ },
83
+ }),
84
+ _descriptionMarkdown: field({
85
+ type: 'object',
86
+ rest: { form: { fieldSource: 'content.descriptionMarkdown' } },
87
+ }),
88
+ },
89
+ },
90
+ onGetSchema,
91
+ 'form',
92
+ );
93
+
94
+ assert.deepEqual(properties?.[1], {
95
+ key: 'content.descriptionMarkdown',
96
+ schemaKey: '_descriptionMarkdown',
97
+ type: 'string',
98
+ });
99
+ });
100
+
101
+ test('schema properties coalesce aliases when the source property has fieldSource', () => {
102
+ const properties = loadSchemaProperties(
103
+ {
104
+ type: 'object',
105
+ properties: {
106
+ content: field({
107
+ type: 'object',
108
+ rest: { fieldSource: 'content.descriptionMarkdown' },
109
+ properties: {
110
+ descriptionMarkdown: field({ type: 'string' }),
111
+ },
112
+ }),
113
+ _descriptionMarkdown: field({
114
+ type: 'object',
115
+ rest: { fieldSource: 'content.descriptionMarkdown' },
116
+ }),
117
+ studentContentForm: field({
118
+ type: 'object',
119
+ rest: { fieldSource: 'content.descriptionMarkdown' },
120
+ }),
121
+ },
122
+ },
123
+ onGetSchema,
124
+ );
125
+
126
+ assert.deepEqual(properties, [
127
+ {
128
+ key: 'content.descriptionMarkdown',
129
+ schemaKey: 'content',
130
+ schemaKeys: ['_descriptionMarkdown', 'studentContentForm'],
131
+ type: 'string',
132
+ },
133
+ ]);
134
+ });
135
+
136
+ test('schema properties coalesce aliases declared before their fieldSource parent', () => {
137
+ const properties = loadSchemaProperties(
138
+ {
139
+ type: 'object',
140
+ properties: {
141
+ _descriptionMarkdown: field({
142
+ type: 'object',
143
+ rest: { fieldSource: 'content.descriptionMarkdown' },
144
+ }),
145
+ content: field({
146
+ type: 'object',
147
+ rest: { fieldSource: 'content.descriptionMarkdown' },
148
+ properties: {
149
+ descriptionMarkdown: field({ type: 'string' }),
150
+ },
151
+ }),
152
+ },
153
+ },
154
+ onGetSchema,
155
+ );
156
+
157
+ assert.deepEqual(properties, [
158
+ {
159
+ key: 'content.descriptionMarkdown',
160
+ schemaKey: '_descriptionMarkdown',
161
+ schemaKeys: ['content'],
162
+ type: 'string',
163
+ },
164
+ ]);
165
+ });
166
+
167
+ test('ordinary schema properties do not gain a schema alias', () => {
168
+ const properties = loadSchemaProperties(
169
+ {
170
+ type: 'object',
171
+ properties: {
172
+ name: field({ type: 'string' }),
173
+ },
174
+ },
175
+ onGetSchema,
176
+ );
177
+
178
+ assert.deepEqual(properties, [{ key: 'name', type: 'string' }]);
179
+ });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-suite-a-zova",
3
- "version": "5.1.153",
3
+ "version": "5.1.154",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "zova",
6
6
  "license": "MIT",
@@ -16,13 +16,13 @@
16
16
  "zova-module-a-boundary": "^5.1.22",
17
17
  "zova-module-a-command": "^5.1.34",
18
18
  "zova-module-a-fetch": "^5.1.25",
19
- "zova-module-a-form": "^5.1.49",
19
+ "zova-module-a-form": "^5.1.50",
20
20
  "zova-module-a-icon": "^5.1.27",
21
21
  "zova-module-a-interceptor": "^5.1.31",
22
22
  "zova-module-a-logger": "^5.1.28",
23
23
  "zova-module-a-meta": "^5.1.22",
24
- "zova-module-a-model": "^5.1.35",
25
- "zova-module-a-openapi": "^5.1.50",
24
+ "zova-module-a-model": "^5.1.36",
25
+ "zova-module-a-openapi": "^5.1.51",
26
26
  "zova-module-a-router": "^5.1.34",
27
27
  "zova-module-a-routerstack": "^5.1.27",
28
28
  "zova-module-a-routertabs": "^5.1.34",