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
@@ -0,0 +1,17 @@
1
+ import type { IApiSchemaOptions } from 'zova-module-a-api';
2
+
3
+ import { BeanBase } from 'zova';
4
+ import { ApiSchema } from 'zova-module-a-api';
5
+
6
+ import { ApiApiCommerceTradeStockBalanceadjustStockPath } from '../api/commerceTradeStockBalance.js';
7
+
8
+ @ApiSchema()
9
+ export class ApiSchemaCommerceTradeStockBalance extends BeanBase {
10
+ adjustStock(options?: IApiSchemaOptions) {
11
+ return this.$sdk.createApiSchemas(
12
+ ApiApiCommerceTradeStockBalanceadjustStockPath,
13
+ 'post',
14
+ options,
15
+ );
16
+ }
17
+ }
@@ -0,0 +1,35 @@
1
+ import type { IResourceTableActionRowOptionsBase } from 'zova-module-a-openapi';
2
+ import type {
3
+ IJsxRenderContextTableCell,
4
+ ITableCellRender,
5
+ NextTableCellRender,
6
+ } from 'zova-module-a-table';
7
+
8
+ import { BeanBase } from 'zova';
9
+ import { TableCell } from 'zova-module-a-table';
10
+
11
+ declare module 'zova-module-a-openapi' {
12
+ export interface IResourceTableActionRowRecord {
13
+ 'commerce-trade:actionAdjustStock'?: ITableCellOptionsActionAdjustStock;
14
+ }
15
+ }
16
+
17
+ export interface ITableCellOptionsActionAdjustStock extends IResourceTableActionRowOptionsBase {}
18
+
19
+ @TableCell<ITableCellOptionsActionAdjustStock>({
20
+ class: 'btn btn-outline btn-secondary join-item',
21
+ })
22
+ export class TableCellActionAdjustStock extends BeanBase implements ITableCellRender {
23
+ render(
24
+ options: ITableCellOptionsActionAdjustStock,
25
+ renderContext: IJsxRenderContextTableCell,
26
+ _next: NextTableCellRender,
27
+ ) {
28
+ return renderContext.$jsx.render(
29
+ 'commerce-trade:tableCellActionAdjustStock',
30
+ options,
31
+ renderContext.$celScope,
32
+ renderContext,
33
+ );
34
+ }
35
+ }
@@ -0,0 +1,138 @@
1
+ import type { SchemaObject } from 'openapi3-ts/oas31';
2
+ import type { TableIdentity } from 'table-identity';
3
+ import type { TypeFormOnSubmitData } from 'zova-module-a-form';
4
+ import type { IJsxRenderContextTableCell } from 'zova-module-a-table';
5
+
6
+ import { BeanControllerBase, Use } from 'zova';
7
+ import { Controller } from 'zova-module-a-bean';
8
+ import { ZForm } from 'zova-module-a-form';
9
+ import { $QueryEnsureLoaded } from 'zova-module-a-model';
10
+
11
+ import type { ApiApiCommerceTradeStockBalanceadjustStockRequestBody } from '../../api/commerceTradeStockBalance.js';
12
+ import type { ITableCellOptionsActionAdjustStock } from '../../bean/tableCell.actionAdjustStock.js';
13
+ import type { ModelStockBalance } from '../../model/stockBalance.js';
14
+
15
+ export interface ControllerTableCellActionAdjustStockProps extends ITableCellOptionsActionAdjustStock {}
16
+
17
+ type StockAdjustmentDraft = Omit<
18
+ ApiApiCommerceTradeStockBalanceadjustStockRequestBody,
19
+ 'correlationId' | 'skuId'
20
+ >;
21
+
22
+ const emptyDraft = (): StockAdjustmentDraft => ({ delta: 0, reason: '' });
23
+
24
+ @Controller()
25
+ export class ControllerTableCellActionAdjustStock extends BeanControllerBase {
26
+ static $propsDefault = {};
27
+
28
+ @Use({ injectionScope: 'host' })
29
+ $$renderContext: IJsxRenderContextTableCell;
30
+
31
+ @Use({ beanFullName: 'commerce-trade.model.stockBalance' })
32
+ $$modelStockBalance: ModelStockBalance;
33
+
34
+ draft: StockAdjustmentDraft = emptyDraft();
35
+ schema?: SchemaObject;
36
+
37
+ get apiSchemasStockAdjust() {
38
+ return this.scope.apiSchema.commerceTradeStockBalance.adjustStock();
39
+ }
40
+
41
+ private get _sku() {
42
+ return this.$$renderContext.cellContext.row.original as {
43
+ available: number;
44
+ code: string;
45
+ id: TableIdentity;
46
+ };
47
+ }
48
+
49
+ private get _mutation() {
50
+ return this.$$modelStockBalance.adjustStock(this._sku.id);
51
+ }
52
+
53
+ private async _ensureSchema() {
54
+ if (this.schema) return;
55
+ await $QueryEnsureLoaded(() => this.apiSchemasStockAdjust.sdk);
56
+ this.schema = this.$computed(() => this.apiSchemasStockAdjust.requestBody);
57
+ }
58
+
59
+ private async _submit(data: TypeFormOnSubmitData<StockAdjustmentDraft>, close: () => void) {
60
+ const mutation = this._mutation;
61
+ if (mutation.isPending) return;
62
+ const delta = Number(data.value.delta);
63
+ const reason = data.value.reason.trim();
64
+ if (!Number.isInteger(delta) || delta === 0 || !reason) return;
65
+ await mutation.mutateAsync({
66
+ skuId: this._sku.id,
67
+ delta,
68
+ reason,
69
+ correlationId: crypto.randomUUID(),
70
+ });
71
+ close();
72
+ }
73
+
74
+ private async _openDialog() {
75
+ await this._ensureSchema();
76
+ this.draft = emptyDraft();
77
+ const dialog = this.$appModal.dialog(
78
+ {
79
+ title: this.scope.locale.AdjustStock(),
80
+ slotDefault: () => {
81
+ return (
82
+ <div class="space-y-4">
83
+ <dl class="grid grid-cols-2 gap-x-4 gap-y-2 text-sm">
84
+ <dt class="text-base-content/70">{this.scope.locale.SkuId()}</dt>
85
+ <dd>{this._sku.code}</dd>
86
+ <dt class="text-base-content/70">{this.scope.locale.Available()}</dt>
87
+ <dd>{this._sku.available}</dd>
88
+ </dl>
89
+ <ZForm
90
+ data={this.draft}
91
+ schema={this.schema}
92
+ onSubmitData={data => this._submit(data, () => dialog.close())}
93
+ onShowError={async ({ error }) => {
94
+ await this.$performCommand('basic-commands:alert', {
95
+ type: 'error',
96
+ text: error.message,
97
+ });
98
+ }}
99
+ slotFooter={$$form => (
100
+ <div class="flex justify-end gap-2">
101
+ {this._mutation.isPending && (
102
+ <span class="loading loading-spinner text-primary"></span>
103
+ )}
104
+ <button class="btn btn-ghost" type="button" onClick={() => dialog.close()}>
105
+ {this.scope.locale.Cancel()}
106
+ </button>
107
+ <button
108
+ class="btn btn-secondary"
109
+ disabled={$$form.formState.isSubmitting || this._mutation.isPending}
110
+ type="submit"
111
+ >
112
+ {this.scope.locale.AdjustStock()}
113
+ </button>
114
+ </div>
115
+ )}
116
+ ></ZForm>
117
+ </div>
118
+ );
119
+ },
120
+ },
121
+ {
122
+ closeOnBackdrop: false,
123
+ closeOnEscape: false,
124
+ maxWidth: 480,
125
+ showCloseButton: true,
126
+ },
127
+ );
128
+ }
129
+
130
+ protected render() {
131
+ const props = this.$props as ControllerTableCellActionAdjustStockProps;
132
+ return (
133
+ <button class={props.class} type="button" onClick={() => this._openDialog()}>
134
+ {this.scope.locale.AdjustStock()}
135
+ </button>
136
+ );
137
+ }
138
+ }
@@ -97,4 +97,7 @@ export default {
97
97
  CompleteMockRefund: 'Complete mock refund',
98
98
  MockRefundCompletionFailed: 'Unable to complete the mock refund. Try again.',
99
99
  MockRefundCompleted: 'The mock refund was completed. The order is being settled.',
100
+ AdjustStock: 'Adjust stock',
101
+ SkuId: 'SKU',
102
+ Available: 'Available',
100
103
  };
@@ -88,4 +88,7 @@ export default {
88
88
  CompleteMockRefund: '完成模拟退款',
89
89
  MockRefundCompletionFailed: '无法完成模拟退款,请重试。',
90
90
  MockRefundCompleted: '模拟退款已完成,订单正在结算。',
91
+ AdjustStock: '调整库存',
92
+ SkuId: 'SKU',
93
+ Available: '可用库存',
91
94
  };
@@ -0,0 +1,36 @@
1
+ import type { TableIdentity } from 'table-identity';
2
+ import type { IDecoratorModelOptions } from 'zova-module-a-model';
3
+ import type { ModelResource } from 'zova-module-rest-resource';
4
+
5
+ import { Use, usePrepareArg } from 'zova';
6
+ import { BeanModelBase, Model } from 'zova-module-a-model';
7
+
8
+ import type {
9
+ ApiApiCommerceTradeStockBalanceadjustStockRequestBody,
10
+ ApiApiCommerceTradeStockBalanceadjustStockResponseBody,
11
+ } from '../api/commerceTradeStockBalance.js';
12
+
13
+ export interface IModelOptionsStockBalance extends IDecoratorModelOptions {}
14
+
15
+ const SkuResource = 'commerce-catalog:sku';
16
+
17
+ @Model<IModelOptionsStockBalance>()
18
+ export class ModelStockBalance extends BeanModelBase {
19
+ @Use({ beanFullName: 'rest-resource.model.resource' })
20
+ protected get $$modelResource(): ModelResource {
21
+ return usePrepareArg(SkuResource, true);
22
+ }
23
+
24
+ adjustStock(id: TableIdentity) {
25
+ return this.$$modelResource.mutationItem<
26
+ ApiApiCommerceTradeStockBalanceadjustStockResponseBody,
27
+ ApiApiCommerceTradeStockBalanceadjustStockRequestBody
28
+ >({
29
+ id,
30
+ action: 'adjustStock',
31
+ mutationFn: async payload => {
32
+ return await this.scope.api.commerceTradeStockBalance.adjustStock(payload);
33
+ },
34
+ });
35
+ }
36
+ }
@@ -159,9 +159,8 @@ export class ControllerPagePayment extends BeanControllerPageBase {
159
159
  for (const [attempt, delay] of SettlementPollDelaysMilliseconds.entries()) {
160
160
  if (delay > 0) await new Promise(resolve => setTimeout(resolve, delay));
161
161
  if (!this._isCurrentSettlementPoll(pollVersion)) return;
162
- let session;
163
162
  try {
164
- session = await this.queryPaymentSession?.refetch();
163
+ await this.queryPaymentSession?.refetch({ bypassPersister: true });
165
164
  } catch (error) {
166
165
  if (isNotFoundError(error)) {
167
166
  this.paymentSessionUnavailable = true;
@@ -171,9 +170,10 @@ export class ControllerPagePayment extends BeanControllerPageBase {
171
170
  throw error;
172
171
  }
173
172
  if (!this._isCurrentSettlementPoll(pollVersion)) return;
174
- const sessionState = session?.data?.state;
173
+ const session = this.queryPaymentSession?.data;
174
+ const sessionState = session?.state;
175
175
  this.pendingSessionState = sessionState;
176
- this.pendingNextAction = session?.data?.nextAction;
176
+ this.pendingNextAction = session?.nextAction;
177
177
  const isSessionTerminal = ['succeeded', 'failed', 'cancelled', 'expired'].includes(
178
178
  sessionState ?? '',
179
179
  );
@@ -302,10 +302,10 @@ export type ApiSchemaCommerceTradeEntityStockBalance =
302
302
  components['schemas']['commerce-trade.entity.stockBalance'];
303
303
  export type ApiSchemaCommerceTradeEntityStockBalancePartial =
304
304
  Partial<ApiSchemaCommerceTradeEntityStockBalance>;
305
- export type ApiSchemaCommerceTradeDtoStockAdjust_0aab216abd3467dd07f61c69172266c2441af477 =
306
- components['schemas']['commerce-trade.dto.stockAdjust_0aab216abd3467dd07f61c69172266c2441af477'];
307
- export type ApiSchemaCommerceTradeDtoStockAdjust_0aab216abd3467dd07f61c69172266c2441af477Partial =
308
- Partial<ApiSchemaCommerceTradeDtoStockAdjust_0aab216abd3467dd07f61c69172266c2441af477>;
305
+ export type ApiSchemaCommerceTradeDtoStockAdjust_6a7c2f0bb21a25da3048650f263577ae4467750e =
306
+ components['schemas']['commerce-trade.dto.stockAdjust_6a7c2f0bb21a25da3048650f263577ae4467750e'];
307
+ export type ApiSchemaCommerceTradeDtoStockAdjust_6a7c2f0bb21a25da3048650f263577ae4467750ePartial =
308
+ Partial<ApiSchemaCommerceTradeDtoStockAdjust_6a7c2f0bb21a25da3048650f263577ae4467750e>;
309
309
  export type ApiSchemaCommerceTradeDtoStockBalanceSelectRes =
310
310
  components['schemas']['commerce-trade.dto.stockBalanceSelectRes'];
311
311
  export type ApiSchemaCommerceTradeDtoStockBalanceSelectResPartial =
@@ -463,10 +463,10 @@ export type ApiSchemaAImageDtoImageView_a83c3e638bca4b30ec8675860cdc52d66f6a16d1
463
463
  components['schemas']['a-image.dto.imageView_a83c3e638bca4b30ec8675860cdc52d66f6a16d1_2d063d28bc7243bed02ebd8bddf1212a93c6305b_efb37794d7c03c65122279f90d79919f009c34e5_1816ff740d81c738ec055c7038bbd93beb9405a7_537cd6552a384183a9457fb6a920bbae337277f6'];
464
464
  export type ApiSchemaAImageDtoImageView_a83c3e638bca4b30ec8675860cdc52d66f6a16d1_2d063d28bc7243bed02ebd8bddf1212a93c6305b_efb37794d7c03c65122279f90d79919f009c34e5_1816ff740d81c738ec055c7038bbd93beb9405a7_537cd6552a384183a9457fb6a920bbae337277f6Partial =
465
465
  Partial<ApiSchemaAImageDtoImageView_a83c3e638bca4b30ec8675860cdc52d66f6a16d1_2d063d28bc7243bed02ebd8bddf1212a93c6305b_efb37794d7c03c65122279f90d79919f009c34e5_1816ff740d81c738ec055c7038bbd93beb9405a7_537cd6552a384183a9457fb6a920bbae337277f6>;
466
- export type ApiSchemaTrainingStudentDtoStudentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_1d66fd9b41b42bee7a7709e4c1b00556fdb4dae3 =
467
- components['schemas']['training-student.dto.studentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_1d66fd9b41b42bee7a7709e4c1b00556fdb4dae3'];
468
- export type ApiSchemaTrainingStudentDtoStudentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_1d66fd9b41b42bee7a7709e4c1b00556fdb4dae3Partial =
469
- Partial<ApiSchemaTrainingStudentDtoStudentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_1d66fd9b41b42bee7a7709e4c1b00556fdb4dae3>;
466
+ export type ApiSchemaTrainingStudentDtoStudentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_93b863fbe913f9389386c3f524075f08b39f48ac =
467
+ components['schemas']['training-student.dto.studentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_93b863fbe913f9389386c3f524075f08b39f48ac'];
468
+ export type ApiSchemaTrainingStudentDtoStudentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_93b863fbe913f9389386c3f524075f08b39f48acPartial =
469
+ Partial<ApiSchemaTrainingStudentDtoStudentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_93b863fbe913f9389386c3f524075f08b39f48ac>;
470
470
  export type ApiSchemaTrainingStudentDtoStudentUpdate =
471
471
  components['schemas']['training-student.dto.studentUpdate'];
472
472
  export type ApiSchemaTrainingStudentDtoStudentUpdatePartial =
@@ -3374,7 +3374,7 @@ export interface components {
3374
3374
  available: number;
3375
3375
  };
3376
3376
  /** @description Adjust Stock */
3377
- 'commerce-trade.dto.stockAdjust_0aab216abd3467dd07f61c69172266c2441af477': {
3377
+ 'commerce-trade.dto.stockAdjust_6a7c2f0bb21a25da3048650f263577ae4467750e': {
3378
3378
  /** @description SKU ID */
3379
3379
  skuId: number | string;
3380
3380
  /** @description Delta */
@@ -3815,6 +3815,8 @@ export interface components {
3815
3815
  /** @description Product title */
3816
3816
  title: string;
3817
3817
  };
3818
+ /** @description Available */
3819
+ available: number;
3818
3820
  /** @description Operations */
3819
3821
  _operationsRow?: unknown;
3820
3822
  };
@@ -4287,7 +4289,7 @@ export interface components {
4287
4289
  | undefined;
4288
4290
  }[]
4289
4291
  | undefined;
4290
- studentContentForm?: {
4292
+ content?: {
4291
4293
  /** @description Description Markdown */
4292
4294
  descriptionMarkdown?: string | undefined;
4293
4295
  };
@@ -4410,7 +4412,7 @@ export interface components {
4410
4412
  signed?: boolean;
4411
4413
  }
4412
4414
  | undefined;
4413
- 'training-student.dto.studentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_1d66fd9b41b42bee7a7709e4c1b00556fdb4dae3':
4415
+ 'training-student.dto.studentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_93b863fbe913f9389386c3f524075f08b39f48ac':
4414
4416
  | {
4415
4417
  /**
4416
4418
  * Format: date-time
@@ -4517,10 +4519,7 @@ export interface components {
4517
4519
  | components['schemas']['training-record.dto.detailRecordSubjectResItem'][]
4518
4520
  | undefined;
4519
4521
  }[];
4520
- studentContentForm?: {
4521
- /** @description ID */
4522
- id: number | string;
4523
- studentId: number | string;
4522
+ content?: {
4524
4523
  /** @description Description Markdown */
4525
4524
  descriptionMarkdown?: string | undefined;
4526
4525
  };
@@ -4528,6 +4527,7 @@ export interface components {
4528
4527
  _trainingRecords?:
4529
4528
  | components['schemas']['training-student.dto.detailRecordResItem'][]
4530
4529
  | undefined;
4530
+ _descriptionMarkdown?: string | undefined;
4531
4531
  }
4532
4532
  | undefined;
4533
4533
  'training-student.dto.studentUpdate': {
@@ -4618,7 +4618,7 @@ export interface components {
4618
4618
  | undefined;
4619
4619
  }[]
4620
4620
  | undefined;
4621
- studentContentForm?: {
4621
+ content?: {
4622
4622
  /**
4623
4623
  * @description Deleted
4624
4624
  * @default false
@@ -4644,7 +4644,7 @@ export interface components {
4644
4644
  /** @description Training Stage */
4645
4645
  level: 1 | 2 | 3;
4646
4646
  /** @description Description */
4647
- description?: string | undefined;
4647
+ descriptionMarkdown?: string | undefined;
4648
4648
  /** @description Description HTML */
4649
4649
  descriptionHtml?: string | undefined;
4650
4650
  /** @description Level Title */
@@ -7226,7 +7226,7 @@ export interface operations {
7226
7226
  };
7227
7227
  requestBody: {
7228
7228
  content: {
7229
- 'application/json': components['schemas']['commerce-trade.dto.stockAdjust_0aab216abd3467dd07f61c69172266c2441af477'];
7229
+ 'application/json': components['schemas']['commerce-trade.dto.stockAdjust_6a7c2f0bb21a25da3048650f263577ae4467750e'];
7230
7230
  };
7231
7231
  };
7232
7232
  responses: {
@@ -8127,7 +8127,7 @@ export interface operations {
8127
8127
  'application/json': {
8128
8128
  code: string;
8129
8129
  message: string;
8130
- data?: components['schemas']['training-student.dto.studentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_1d66fd9b41b42bee7a7709e4c1b00556fdb4dae3'];
8130
+ data?: components['schemas']['training-student.dto.studentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_93b863fbe913f9389386c3f524075f08b39f48ac'];
8131
8131
  };
8132
8132
  };
8133
8133
  };
@@ -40,13 +40,13 @@ export class TableCellActionSummary extends BeanBase implements ITableCellRender
40
40
  true,
41
41
  )) as ModelStudent;
42
42
  const querySummary = modelStudent.summary(id);
43
- const { data: summary } = await querySummary.refetch();
43
+ await querySummary.refetch({ bypassPersister: true });
44
44
  $host.$appModal.dialog(
45
45
  {
46
46
  title: this.scope.locale.Summary(),
47
47
  slotDefault: () => (
48
48
  <div class="student-summary-description">
49
- <ZMarkdownHtml html={summary?.descriptionHtml} />
49
+ <ZMarkdownHtml html={querySummary.data?.descriptionHtml ?? ''} />
50
50
  </div>
51
51
  ),
52
52
  },
@@ -290,6 +290,8 @@ export class BehaviorAppModal extends BeanBehaviorBase<
290
290
  }}
291
291
  ></div>
292
292
  <div
293
+ role="dialog"
294
+ aria-modal="true"
293
295
  class="card bg-base-100 shadow-2xl relative w-full max-h-[calc(100vh-2rem)]"
294
296
  style={style}
295
297
  >
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-rest-resource",
3
- "version": "5.1.46",
3
+ "version": "5.1.47",
4
4
  "gitHead": "4dece229b6d3f4735930e833afcb4b95ec51bf86",
5
5
  "description": "",
6
6
  "keywords": [
@@ -1,5 +1,5 @@
1
1
  import type { TableIdentity } from 'table-identity';
2
- import type { DataMutation, IDecoratorModelOptions } from 'zova-module-a-model';
2
+ import type { DataMutation, IDecoratorModelOptions, QueryMetaPersister } from 'zova-module-a-model';
3
3
  import type {
4
4
  IFormMeta,
5
5
  IFormProvider,
@@ -27,6 +27,7 @@ interface IModelResourceQueryItemOptions<TData> {
27
27
  meta?: {
28
28
  disableSuspenseOnInit?: boolean;
29
29
  disableErrorEffect?: boolean;
30
+ persister?: QueryMetaPersister | boolean;
30
31
  };
31
32
  }
32
33
 
@@ -17,6 +17,17 @@ void requiredBody.delete(id).mutateAsync({ reason: 'duplicate' });
17
17
  void optionalBody.delete(id).mutateAsync();
18
18
  void optionalBody.delete(id).mutateAsync({ reason: 'duplicate' });
19
19
 
20
+ const queryItem = standard.queryItem({
21
+ id,
22
+ action: 'summary',
23
+ queryFn: async () => ({ id: 1 }),
24
+ });
25
+ void queryItem.refetch({
26
+ bypassPersister: true,
27
+ cancelRefetch: false,
28
+ throwOnError: true,
29
+ });
30
+
20
31
  // @ts-expect-error required DELETE bodies cannot be omitted
21
32
  void requiredBody.delete(id).mutateAsync();
22
33
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-suite-a-cabloy",
3
- "version": "5.1.47",
3
+ "version": "5.1.48",
4
4
  "gitHead": "4dece229b6d3f4735930e833afcb4b95ec51bf86",
5
5
  "description": "",
6
6
  "author": "",
@@ -8,7 +8,7 @@
8
8
  "type": "module",
9
9
  "dependencies": {
10
10
  "zova-module-a-rbac": "^5.0.1",
11
- "zova-module-rest-resource": "^5.1.46"
11
+ "zova-module-rest-resource": "^5.1.47"
12
12
  },
13
13
  "title": "a-cabloy"
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-form",
3
- "version": "5.1.49",
3
+ "version": "5.1.50",
4
4
  "gitHead": "09d901d17140a80ee0764211b441cda72fd94663",
5
5
  "description": "",
6
6
  "keywords": [
@@ -24,12 +24,21 @@ export function resolveFormLayout(
24
24
  layout: IFormLayout,
25
25
  properties: ISchemaObjectExtensionField[] | undefined,
26
26
  ): IResolvedFormLayout {
27
+ const visibleProperties = properties?.filter(item => item.rest?.visible !== false) ?? [];
27
28
  const propertyNames = new Set(
28
- properties
29
- ?.filter(item => item.rest?.visible !== false)
30
- .map(item => item.key)
31
- .filter(Boolean) as string[],
29
+ visibleProperties.map(item => item.key).filter(Boolean) as string[],
32
30
  );
31
+ const propertyAliases = new Map<string, Set<string>>();
32
+ for (const property of visibleProperties) {
33
+ if (!property.key) continue;
34
+ const schemaKeys = [property.schemaKey, ...(property.schemaKeys ?? [])];
35
+ for (const schemaKey of schemaKeys) {
36
+ if (!schemaKey || schemaKey === property.key) continue;
37
+ const aliases = propertyAliases.get(schemaKey) ?? new Set<string>();
38
+ aliases.add(property.key);
39
+ propertyAliases.set(schemaKey, aliases);
40
+ }
41
+ }
33
42
  const fieldNames = new Set<string>();
34
43
  const nodeIds = new Set<string>();
35
44
  const diagnostics: IFormLayoutDiagnostic[] = [];
@@ -41,6 +50,7 @@ export function resolveFormLayout(
41
50
  [index],
42
51
  [],
43
52
  propertyNames,
53
+ propertyAliases,
44
54
  fieldNames,
45
55
  nodeIds,
46
56
  diagnostics,
@@ -62,13 +72,22 @@ function resolveNode(
62
72
  indexPath: number[],
63
73
  tabPath: IResolvedFormLayout['fieldTabPaths'][string],
64
74
  propertyNames: Set<string>,
75
+ propertyAliases: Map<string, Set<string>>,
65
76
  fieldNames: Set<string>,
66
77
  nodeIds: Set<string>,
67
78
  diagnostics: IFormLayoutDiagnostic[],
68
79
  fieldTabPaths: IResolvedFormLayout['fieldTabPaths'],
69
80
  ): IResolvedFormLayoutNode | undefined {
70
81
  if (node.type === 'field') {
71
- return resolveField(node, tabPath, propertyNames, fieldNames, diagnostics, fieldTabPaths);
82
+ return resolveField(
83
+ node,
84
+ tabPath,
85
+ propertyNames,
86
+ propertyAliases,
87
+ fieldNames,
88
+ diagnostics,
89
+ fieldTabPaths,
90
+ );
72
91
  }
73
92
  if (node.type === 'block') {
74
93
  return node;
@@ -78,6 +97,7 @@ function resolveNode(
78
97
  node,
79
98
  indexPath,
80
99
  propertyNames,
100
+ propertyAliases,
81
101
  fieldNames,
82
102
  nodeIds,
83
103
  diagnostics,
@@ -89,7 +109,15 @@ function resolveNode(
89
109
  if (node.type === 'section') {
90
110
  const children = node.children
91
111
  .map(item =>
92
- resolveLeaf(item, tabPath, propertyNames, fieldNames, diagnostics, fieldTabPaths),
112
+ resolveLeaf(
113
+ item,
114
+ tabPath,
115
+ propertyNames,
116
+ propertyAliases,
117
+ fieldNames,
118
+ diagnostics,
119
+ fieldTabPaths,
120
+ ),
93
121
  )
94
122
  .filter(Boolean) as IResolvedFormLayoutLeaf[];
95
123
  return children.length ? { ...node, id, children } : undefined;
@@ -101,6 +129,7 @@ function resolveNode(
101
129
  [...indexPath, index],
102
130
  tabPath,
103
131
  propertyNames,
132
+ propertyAliases,
104
133
  fieldNames,
105
134
  nodeIds,
106
135
  diagnostics,
@@ -117,18 +146,28 @@ function resolveLeaf(
117
146
  node: IFormLayoutLeaf,
118
147
  tabPath: IResolvedFormLayout['fieldTabPaths'][string],
119
148
  propertyNames: Set<string>,
149
+ propertyAliases: Map<string, Set<string>>,
120
150
  fieldNames: Set<string>,
121
151
  diagnostics: IFormLayoutDiagnostic[],
122
152
  fieldTabPaths: IResolvedFormLayout['fieldTabPaths'],
123
153
  ): IResolvedFormLayoutLeaf | undefined {
124
154
  if (node.type === 'block') return node;
125
- return resolveField(node, tabPath, propertyNames, fieldNames, diagnostics, fieldTabPaths);
155
+ return resolveField(
156
+ node,
157
+ tabPath,
158
+ propertyNames,
159
+ propertyAliases,
160
+ fieldNames,
161
+ diagnostics,
162
+ fieldTabPaths,
163
+ );
126
164
  }
127
165
 
128
166
  function resolveTabs(
129
167
  node: IFormLayoutTabs,
130
168
  indexPath: number[],
131
169
  propertyNames: Set<string>,
170
+ propertyAliases: Map<string, Set<string>>,
132
171
  fieldNames: Set<string>,
133
172
  nodeIds: Set<string>,
134
173
  diagnostics: IFormLayoutDiagnostic[],
@@ -143,6 +182,7 @@ function resolveTabs(
143
182
  [...indexPath, index],
144
183
  id,
145
184
  propertyNames,
185
+ propertyAliases,
146
186
  fieldNames,
147
187
  nodeIds,
148
188
  diagnostics,
@@ -158,6 +198,7 @@ function resolveTab(
158
198
  indexPath: number[],
159
199
  tabsId: string,
160
200
  propertyNames: Set<string>,
201
+ propertyAliases: Map<string, Set<string>>,
161
202
  fieldNames: Set<string>,
162
203
  nodeIds: Set<string>,
163
204
  diagnostics: IFormLayoutDiagnostic[],
@@ -173,6 +214,7 @@ function resolveTab(
173
214
  [...indexPath, index],
174
215
  tabPath,
175
216
  propertyNames,
217
+ propertyAliases,
176
218
  fieldNames,
177
219
  nodeIds,
178
220
  diagnostics,
@@ -189,11 +231,12 @@ function resolveField(
189
231
  node: IFormLayoutField,
190
232
  tabPath: IResolvedFormLayout['fieldTabPaths'][string],
191
233
  propertyNames: Set<string>,
234
+ propertyAliases: Map<string, Set<string>>,
192
235
  fieldNames: Set<string>,
193
236
  diagnostics: IFormLayoutDiagnostic[],
194
237
  fieldTabPaths: IResolvedFormLayout['fieldTabPaths'],
195
238
  ): IResolvedFormLayoutField | undefined {
196
- const name = resolveFieldName(node.name, propertyNames);
239
+ const name = resolveFieldName(node.name, propertyNames, propertyAliases);
197
240
  if (!name) {
198
241
  diagnostics.push({ type: 'unknownField', value: node.name });
199
242
  return;
@@ -207,8 +250,14 @@ function resolveField(
207
250
  return name === node.name ? node : { ...node, name };
208
251
  }
209
252
 
210
- function resolveFieldName(name: string, propertyNames: Set<string>) {
253
+ function resolveFieldName(
254
+ name: string,
255
+ propertyNames: Set<string>,
256
+ propertyAliases: Map<string, Set<string>>,
257
+ ) {
211
258
  if (propertyNames.has(name)) return name;
259
+ const aliases = propertyAliases.get(name);
260
+ if (aliases?.size === 1) return aliases.values().next().value;
212
261
  const fieldSourcePrefix = `${name}.`;
213
262
  const fieldSources = [...propertyNames].filter(item => item.startsWith(fieldSourcePrefix));
214
263
  return fieldSources.length === 1 ? fieldSources[0] : undefined;