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
@@ -357,114 +357,6 @@ declare module 'vona-module-a-orm' {
357
357
  }
358
358
  }
359
359
  /** model: end */
360
- /** service: begin */
361
- export * from '../service/category.ts';
362
- export * from '../service/product.ts';
363
- export * from '../service/sku.ts';
364
-
365
- import 'vona-module-a-bean';
366
- declare module 'vona-module-a-bean' {
367
-
368
- export interface IServiceRecord {
369
- 'commerce-catalog:category': never;
370
- 'commerce-catalog:product': never;
371
- 'commerce-catalog:sku': never;
372
- }
373
-
374
-
375
- }
376
- declare module 'vona-module-commerce-catalog' {
377
-
378
- export interface ServiceCategory {
379
- /** @internal */
380
- get scope(): ScopeModuleCommerceCatalog;
381
- }
382
-
383
- export interface ServiceCategory {
384
- get $beanFullName(): 'commerce-catalog.service.category';
385
- get $onionName(): 'commerce-catalog:category';
386
- }
387
-
388
- export interface ServiceProduct {
389
- /** @internal */
390
- get scope(): ScopeModuleCommerceCatalog;
391
- }
392
-
393
- export interface ServiceProduct {
394
- get $beanFullName(): 'commerce-catalog.service.product';
395
- get $onionName(): 'commerce-catalog:product';
396
- }
397
-
398
- export interface ServiceSku {
399
- /** @internal */
400
- get scope(): ScopeModuleCommerceCatalog;
401
- }
402
-
403
- export interface ServiceSku {
404
- get $beanFullName(): 'commerce-catalog.service.sku';
405
- get $onionName(): 'commerce-catalog:sku';
406
- }
407
- }
408
- /** service: end */
409
- /** service: begin */
410
- import type { ServiceCategory } from '../service/category.ts';
411
- import type { ServiceProduct } from '../service/product.ts';
412
- import type { ServiceSku } from '../service/sku.ts';
413
- export interface IModuleService {
414
- 'category': ServiceCategory;
415
- 'product': ServiceProduct;
416
- 'sku': ServiceSku;
417
- }
418
- /** service: end */
419
- /** service: begin */
420
-
421
- import 'vona';
422
- declare module 'vona' {
423
- export interface IBeanRecordGeneral {
424
- 'commerce-catalog.service.category': ServiceCategory;
425
- 'commerce-catalog.service.product': ServiceProduct;
426
- 'commerce-catalog.service.sku': ServiceSku;
427
- }
428
- }
429
- /** service: end */
430
- /** meta: begin */
431
- export * from '../bean/meta.index.ts';
432
- export * from '../bean/meta.version.ts';
433
- import type { IMetaOptionsIndex } from 'vona-module-a-index';
434
- import 'vona-module-a-meta';
435
- declare module 'vona-module-a-meta' {
436
-
437
- export interface IMetaRecord {
438
- 'commerce-catalog:index': IMetaOptionsIndex;
439
- 'commerce-catalog:version': never;
440
- }
441
-
442
-
443
- }
444
- declare module 'vona-module-commerce-catalog' {
445
-
446
- export interface MetaIndex {
447
- /** @internal */
448
- get scope(): ScopeModuleCommerceCatalog;
449
- }
450
-
451
- export interface MetaIndex {
452
- get $beanFullName(): 'commerce-catalog.meta.index';
453
- get $onionName(): 'commerce-catalog:index';
454
- get $onionOptions(): IMetaOptionsIndex;
455
- }
456
-
457
- export interface MetaVersion {
458
- /** @internal */
459
- get scope(): ScopeModuleCommerceCatalog;
460
- }
461
-
462
- export interface MetaVersion {
463
- get $beanFullName(): 'commerce-catalog.meta.version';
464
- get $onionName(): 'commerce-catalog:version';
465
- }
466
- }
467
- /** meta: end */
468
360
  /** dto: begin */
469
361
  export * from '../dto/categoryCreate.tsx';
470
362
  export * from '../dto/categorySelectReq.tsx';
@@ -803,6 +695,114 @@ import 'vona-module-a-openapi';
803
695
  }
804
696
 
805
697
  /** controller: end */
698
+ /** service: begin */
699
+ export * from '../service/category.ts';
700
+ export * from '../service/product.ts';
701
+ export * from '../service/sku.ts';
702
+
703
+ import 'vona-module-a-bean';
704
+ declare module 'vona-module-a-bean' {
705
+
706
+ export interface IServiceRecord {
707
+ 'commerce-catalog:category': never;
708
+ 'commerce-catalog:product': never;
709
+ 'commerce-catalog:sku': never;
710
+ }
711
+
712
+
713
+ }
714
+ declare module 'vona-module-commerce-catalog' {
715
+
716
+ export interface ServiceCategory {
717
+ /** @internal */
718
+ get scope(): ScopeModuleCommerceCatalog;
719
+ }
720
+
721
+ export interface ServiceCategory {
722
+ get $beanFullName(): 'commerce-catalog.service.category';
723
+ get $onionName(): 'commerce-catalog:category';
724
+ }
725
+
726
+ export interface ServiceProduct {
727
+ /** @internal */
728
+ get scope(): ScopeModuleCommerceCatalog;
729
+ }
730
+
731
+ export interface ServiceProduct {
732
+ get $beanFullName(): 'commerce-catalog.service.product';
733
+ get $onionName(): 'commerce-catalog:product';
734
+ }
735
+
736
+ export interface ServiceSku {
737
+ /** @internal */
738
+ get scope(): ScopeModuleCommerceCatalog;
739
+ }
740
+
741
+ export interface ServiceSku {
742
+ get $beanFullName(): 'commerce-catalog.service.sku';
743
+ get $onionName(): 'commerce-catalog:sku';
744
+ }
745
+ }
746
+ /** service: end */
747
+ /** service: begin */
748
+ import type { ServiceCategory } from '../service/category.ts';
749
+ import type { ServiceProduct } from '../service/product.ts';
750
+ import type { ServiceSku } from '../service/sku.ts';
751
+ export interface IModuleService {
752
+ 'category': ServiceCategory;
753
+ 'product': ServiceProduct;
754
+ 'sku': ServiceSku;
755
+ }
756
+ /** service: end */
757
+ /** service: begin */
758
+
759
+ import 'vona';
760
+ declare module 'vona' {
761
+ export interface IBeanRecordGeneral {
762
+ 'commerce-catalog.service.category': ServiceCategory;
763
+ 'commerce-catalog.service.product': ServiceProduct;
764
+ 'commerce-catalog.service.sku': ServiceSku;
765
+ }
766
+ }
767
+ /** service: end */
768
+ /** meta: begin */
769
+ export * from '../bean/meta.index.ts';
770
+ export * from '../bean/meta.version.ts';
771
+ import type { IMetaOptionsIndex } from 'vona-module-a-index';
772
+ import 'vona-module-a-meta';
773
+ declare module 'vona-module-a-meta' {
774
+
775
+ export interface IMetaRecord {
776
+ 'commerce-catalog:index': IMetaOptionsIndex;
777
+ 'commerce-catalog:version': never;
778
+ }
779
+
780
+
781
+ }
782
+ declare module 'vona-module-commerce-catalog' {
783
+
784
+ export interface MetaIndex {
785
+ /** @internal */
786
+ get scope(): ScopeModuleCommerceCatalog;
787
+ }
788
+
789
+ export interface MetaIndex {
790
+ get $beanFullName(): 'commerce-catalog.meta.index';
791
+ get $onionName(): 'commerce-catalog:index';
792
+ get $onionOptions(): IMetaOptionsIndex;
793
+ }
794
+
795
+ export interface MetaVersion {
796
+ /** @internal */
797
+ get scope(): ScopeModuleCommerceCatalog;
798
+ }
799
+
800
+ export interface MetaVersion {
801
+ get $beanFullName(): 'commerce-catalog.meta.version';
802
+ get $onionName(): 'commerce-catalog:version';
803
+ }
804
+ }
805
+ /** meta: end */
806
806
  /** ssrMenu: begin */
807
807
  export * from '../bean/ssrMenu.category.ts';
808
808
  export * from '../bean/ssrMenu.product.ts';
@@ -3,6 +3,7 @@ import type { IDecoratorDtoOptions } from 'vona-module-a-web';
3
3
  import { Api, v } from 'vona-module-a-openapiutils';
4
4
  import { $Dto } from 'vona-module-a-orm';
5
5
  import { Dto } from 'vona-module-a-web';
6
+ import { z } from 'zod';
6
7
  import { ZovaRender } from 'zova-rest-cabloy-basic-admin';
7
8
 
8
9
  import { $locale } from '../.metadata/locales.ts';
@@ -62,11 +63,22 @@ export class DtoSkuSelectResItem extends $Dto.get(() => ModelSku, {
62
63
  product: { columns: ['id', 'title'] },
63
64
  },
64
65
  }) {
66
+ @Api.field(
67
+ v.title($locale('Available')),
68
+ v.required(),
69
+ z.number().int().nonnegative(),
70
+ ZovaRender.order(5),
71
+ )
72
+ available: number;
73
+
65
74
  @Api.field(
66
75
  v.title($locale('Operations')),
67
76
  ZovaRender.order(1, 'max'),
68
77
  ZovaRender.cell('basic-table:actionOperationsRow', {
69
78
  actions: [
79
+ ZovaRender.tableActionRow('commerce-trade:actionAdjustStock', {
80
+ permission: { actionInherit: 'update' },
81
+ }),
70
82
  ZovaRender.tableActionRow('basic-table:actionUpdate'),
71
83
  ZovaRender.tableActionRow('basic-table:actionDelete'),
72
84
  ],
@@ -28,13 +28,31 @@ export class ServiceSku extends BeanBase {
28
28
  }
29
29
 
30
30
  async select(params?: IQueryParams<ModelSku>): Promise<DtoSkuSelectRes> {
31
- return await this.scope.model.sku.selectAndCount({
31
+ const result = await this.scope.model.sku.selectAndCount({
32
32
  ...params,
33
33
  include: {
34
34
  ...params?.include,
35
35
  product: { columns: ['id', 'title'] },
36
36
  },
37
37
  });
38
+ if (result.list.length === 0) return result as unknown as DtoSkuSelectRes;
39
+
40
+ const balances = await this.$scope.commerceTrade.model.stockBalance.select({
41
+ columns: ['skuId', 'available'],
42
+ where: {
43
+ skuId: result.list.map(sku => sku.id),
44
+ },
45
+ });
46
+ const availableBySkuId = new Map(
47
+ balances.map(balance => [String(balance.skuId), balance.available]),
48
+ );
49
+ return {
50
+ ...result,
51
+ list: result.list.map(sku => ({
52
+ ...sku,
53
+ available: availableBySkuId.get(String(sku.id)) ?? 0,
54
+ })),
55
+ } as DtoSkuSelectRes;
38
56
  }
39
57
 
40
58
  async view(id: TableIdentity): Promise<DtoSkuView | undefined> {
@@ -178,12 +178,21 @@ describe('skuPresentation.test.ts', () => {
178
178
  listComponent.properties.productId.rest?.table?.columnProps,
179
179
  productPickerOptions,
180
180
  );
181
+ assert.equal(listComponent.properties.available.rest?.table?.order, undefined);
182
+ assert.equal(listComponent.properties.available.rest?.table?.render, undefined);
183
+ assert.equal(listComponent.properties.available.type, 'integer');
184
+ assert.equal(listComponent.properties.available.minimum, 0);
185
+ assert.equal(listComponent.properties.available.title.toJSON(), 'Available');
186
+ const actions = listComponent.properties._operationsRow.rest.table.columnProps.actions;
181
187
  assert.deepEqual(
182
- listComponent.properties._operationsRow.rest.table.columnProps.actions.map(
183
- (action: any) => action.render,
184
- ),
185
- ['basic-table:actionUpdate', 'basic-table:actionDelete'],
188
+ actions.map((action: any) => action.render),
189
+ [
190
+ 'commerce-trade:actionAdjustStock',
191
+ 'basic-table:actionUpdate',
192
+ 'basic-table:actionDelete',
193
+ ],
186
194
  );
195
+ assert.deepEqual(actions[0].options.permission, { actionInherit: 'update' });
187
196
 
188
197
  const filterBlock = listComponent.rest.blocks[0].options.blocks[0];
189
198
  const filterLayout = filterBlock.options.blocks[0].options.formLayout;
@@ -204,6 +213,7 @@ describe('skuPresentation.test.ts', () => {
204
213
  let categoryId: number | string | undefined;
205
214
  let productId: number | string | undefined;
206
215
  let skuId: number | string | undefined;
216
+ let skuIdWithBalance: number | string | undefined;
207
217
  await app.bean.passport.signinMock();
208
218
  try {
209
219
  categoryId = await app.bean.executor.performAction('post', '/commerce/catalog/category', {
@@ -224,6 +234,26 @@ describe('skuPresentation.test.ts', () => {
224
234
  lifecycle: 'draft',
225
235
  },
226
236
  });
237
+ const skuIdWithBalance = await app.bean.executor.performAction(
238
+ 'post',
239
+ '/commerce/catalog/sku',
240
+ {
241
+ body: {
242
+ code: `presentation-sku-balance-${suffix}`,
243
+ productId,
244
+ priceCents: 2345,
245
+ lifecycle: 'draft',
246
+ },
247
+ },
248
+ );
249
+ await app.bean.executor.performAction('post', '/commerce/trade/stockBalance/adjustStock', {
250
+ body: {
251
+ skuId: skuIdWithBalance,
252
+ delta: 7,
253
+ reason: `presentation stock ${suffix}`,
254
+ correlationId: `presentation-${suffix}`,
255
+ },
256
+ });
227
257
 
228
258
  const view: any = await app.bean.executor.performAction(
229
259
  'get',
@@ -247,12 +277,31 @@ describe('skuPresentation.test.ts', () => {
247
277
  });
248
278
  assert.equal(select.list.length, 1);
249
279
  assert.equal(String(select.list[0].id), String(skuId));
280
+ assert.equal(select.list[0].available, 0);
250
281
  assert.deepEqual(select.list[0].product, {
251
282
  id: productId,
252
283
  title: `presentation-sku-product-${suffix}`,
253
284
  });
254
285
  assert.equal(select.list[0].attributes, undefined);
286
+
287
+ const balanceSelect: any = await app.bean.executor.performAction(
288
+ 'get',
289
+ '/commerce/catalog/sku',
290
+ { query: { code: `presentation-sku-balance-${suffix}` } },
291
+ );
292
+ assert.equal(balanceSelect.list.length, 1);
293
+ assert.equal(String(balanceSelect.list[0].id), String(skuIdWithBalance));
294
+ assert.equal(balanceSelect.list[0].available, 7);
255
295
  } finally {
296
+ const tradeScope = app.scope('commerce-trade');
297
+ if (skuIdWithBalance) {
298
+ await tradeScope.model.stockAudit.delete({ skuId: skuIdWithBalance });
299
+ await tradeScope.model.stockReservation.delete({ skuId: skuIdWithBalance });
300
+ await tradeScope.model.stockBalance.delete({ skuId: skuIdWithBalance });
301
+ await app.bean.executor.performAction('delete', '/commerce/catalog/sku/:id', {
302
+ params: { id: skuIdWithBalance },
303
+ });
304
+ }
256
305
  if (skuId) {
257
306
  await app.bean.executor.performAction('delete', '/commerce/catalog/sku/:id', {
258
307
  params: { id: skuId },
@@ -675,154 +675,6 @@ declare module 'vona-module-a-orm' {
675
675
  }
676
676
  }
677
677
  /** model: end */
678
- /** bean: begin */
679
- export * from '../bean/bean.scheduleOrderExpiry.ts';
680
-
681
- import 'vona';
682
- declare module 'vona' {
683
-
684
-
685
- }
686
- declare module 'vona-module-commerce-trade' {
687
-
688
- export interface BeanScheduleOrderExpiry {
689
- /** @internal */
690
- get scope(): ScopeModuleCommerceTrade;
691
- }
692
- }
693
- /** bean: end */
694
- /** bean: begin */
695
- import type { BeanScheduleOrderExpiry } from '../bean/bean.scheduleOrderExpiry.ts';
696
- import 'vona';
697
- declare module 'vona' {
698
- export interface IBeanRecordGlobal {
699
- 'scheduleOrderExpiry': BeanScheduleOrderExpiry;
700
- }
701
- }
702
- /** bean: end */
703
- /** service: begin */
704
- export * from '../service/cart.ts';
705
- export * from '../service/order.ts';
706
- export * from '../service/stockAudit.ts';
707
- export * from '../service/stockBalance.ts';
708
-
709
- import 'vona-module-a-bean';
710
- declare module 'vona-module-a-bean' {
711
-
712
- export interface IServiceRecord {
713
- 'commerce-trade:cart': never;
714
- 'commerce-trade:order': never;
715
- 'commerce-trade:stockAudit': never;
716
- 'commerce-trade:stockBalance': never;
717
- }
718
-
719
-
720
- }
721
- declare module 'vona-module-commerce-trade' {
722
-
723
- export interface ServiceCart {
724
- /** @internal */
725
- get scope(): ScopeModuleCommerceTrade;
726
- }
727
-
728
- export interface ServiceCart {
729
- get $beanFullName(): 'commerce-trade.service.cart';
730
- get $onionName(): 'commerce-trade:cart';
731
- }
732
-
733
- export interface ServiceOrder {
734
- /** @internal */
735
- get scope(): ScopeModuleCommerceTrade;
736
- }
737
-
738
- export interface ServiceOrder {
739
- get $beanFullName(): 'commerce-trade.service.order';
740
- get $onionName(): 'commerce-trade:order';
741
- }
742
-
743
- export interface ServiceStockAudit {
744
- /** @internal */
745
- get scope(): ScopeModuleCommerceTrade;
746
- }
747
-
748
- export interface ServiceStockAudit {
749
- get $beanFullName(): 'commerce-trade.service.stockAudit';
750
- get $onionName(): 'commerce-trade:stockAudit';
751
- }
752
-
753
- export interface ServiceStockBalance {
754
- /** @internal */
755
- get scope(): ScopeModuleCommerceTrade;
756
- }
757
-
758
- export interface ServiceStockBalance {
759
- get $beanFullName(): 'commerce-trade.service.stockBalance';
760
- get $onionName(): 'commerce-trade:stockBalance';
761
- }
762
- }
763
- /** service: end */
764
- /** service: begin */
765
- import type { ServiceCart } from '../service/cart.ts';
766
- import type { ServiceOrder } from '../service/order.ts';
767
- import type { ServiceStockAudit } from '../service/stockAudit.ts';
768
- import type { ServiceStockBalance } from '../service/stockBalance.ts';
769
- export interface IModuleService {
770
- 'cart': ServiceCart;
771
- 'order': ServiceOrder;
772
- 'stockAudit': ServiceStockAudit;
773
- 'stockBalance': ServiceStockBalance;
774
- }
775
- /** service: end */
776
- /** service: begin */
777
-
778
- import 'vona';
779
- declare module 'vona' {
780
- export interface IBeanRecordGeneral {
781
- 'commerce-trade.service.cart': ServiceCart;
782
- 'commerce-trade.service.order': ServiceOrder;
783
- 'commerce-trade.service.stockAudit': ServiceStockAudit;
784
- 'commerce-trade.service.stockBalance': ServiceStockBalance;
785
- }
786
- }
787
- /** service: end */
788
- /** meta: begin */
789
- export * from '../bean/meta.index.ts';
790
- export * from '../bean/meta.version.ts';
791
- import type { IMetaOptionsIndex } from 'vona-module-a-index';
792
- import 'vona-module-a-meta';
793
- declare module 'vona-module-a-meta' {
794
-
795
- export interface IMetaRecord {
796
- 'commerce-trade:index': IMetaOptionsIndex;
797
- 'commerce-trade:version': never;
798
- }
799
-
800
-
801
- }
802
- declare module 'vona-module-commerce-trade' {
803
-
804
- export interface MetaIndex {
805
- /** @internal */
806
- get scope(): ScopeModuleCommerceTrade;
807
- }
808
-
809
- export interface MetaIndex {
810
- get $beanFullName(): 'commerce-trade.meta.index';
811
- get $onionName(): 'commerce-trade:index';
812
- get $onionOptions(): IMetaOptionsIndex;
813
- }
814
-
815
- export interface MetaVersion {
816
- /** @internal */
817
- get scope(): ScopeModuleCommerceTrade;
818
- }
819
-
820
- export interface MetaVersion {
821
- get $beanFullName(): 'commerce-trade.meta.version';
822
- get $onionName(): 'commerce-trade:version';
823
- }
824
- }
825
- /** meta: end */
826
678
  /** dto: begin */
827
679
  export * from '../dto/cartAddItem.tsx';
828
680
  export * from '../dto/cartItem.tsx';
@@ -1368,6 +1220,154 @@ import 'vona-module-a-openapi';
1368
1220
  }
1369
1221
 
1370
1222
  /** controller: end */
1223
+ /** bean: begin */
1224
+ export * from '../bean/bean.scheduleOrderExpiry.ts';
1225
+
1226
+ import 'vona';
1227
+ declare module 'vona' {
1228
+
1229
+
1230
+ }
1231
+ declare module 'vona-module-commerce-trade' {
1232
+
1233
+ export interface BeanScheduleOrderExpiry {
1234
+ /** @internal */
1235
+ get scope(): ScopeModuleCommerceTrade;
1236
+ }
1237
+ }
1238
+ /** bean: end */
1239
+ /** bean: begin */
1240
+ import type { BeanScheduleOrderExpiry } from '../bean/bean.scheduleOrderExpiry.ts';
1241
+ import 'vona';
1242
+ declare module 'vona' {
1243
+ export interface IBeanRecordGlobal {
1244
+ 'scheduleOrderExpiry': BeanScheduleOrderExpiry;
1245
+ }
1246
+ }
1247
+ /** bean: end */
1248
+ /** service: begin */
1249
+ export * from '../service/cart.ts';
1250
+ export * from '../service/order.ts';
1251
+ export * from '../service/stockAudit.ts';
1252
+ export * from '../service/stockBalance.ts';
1253
+
1254
+ import 'vona-module-a-bean';
1255
+ declare module 'vona-module-a-bean' {
1256
+
1257
+ export interface IServiceRecord {
1258
+ 'commerce-trade:cart': never;
1259
+ 'commerce-trade:order': never;
1260
+ 'commerce-trade:stockAudit': never;
1261
+ 'commerce-trade:stockBalance': never;
1262
+ }
1263
+
1264
+
1265
+ }
1266
+ declare module 'vona-module-commerce-trade' {
1267
+
1268
+ export interface ServiceCart {
1269
+ /** @internal */
1270
+ get scope(): ScopeModuleCommerceTrade;
1271
+ }
1272
+
1273
+ export interface ServiceCart {
1274
+ get $beanFullName(): 'commerce-trade.service.cart';
1275
+ get $onionName(): 'commerce-trade:cart';
1276
+ }
1277
+
1278
+ export interface ServiceOrder {
1279
+ /** @internal */
1280
+ get scope(): ScopeModuleCommerceTrade;
1281
+ }
1282
+
1283
+ export interface ServiceOrder {
1284
+ get $beanFullName(): 'commerce-trade.service.order';
1285
+ get $onionName(): 'commerce-trade:order';
1286
+ }
1287
+
1288
+ export interface ServiceStockAudit {
1289
+ /** @internal */
1290
+ get scope(): ScopeModuleCommerceTrade;
1291
+ }
1292
+
1293
+ export interface ServiceStockAudit {
1294
+ get $beanFullName(): 'commerce-trade.service.stockAudit';
1295
+ get $onionName(): 'commerce-trade:stockAudit';
1296
+ }
1297
+
1298
+ export interface ServiceStockBalance {
1299
+ /** @internal */
1300
+ get scope(): ScopeModuleCommerceTrade;
1301
+ }
1302
+
1303
+ export interface ServiceStockBalance {
1304
+ get $beanFullName(): 'commerce-trade.service.stockBalance';
1305
+ get $onionName(): 'commerce-trade:stockBalance';
1306
+ }
1307
+ }
1308
+ /** service: end */
1309
+ /** service: begin */
1310
+ import type { ServiceCart } from '../service/cart.ts';
1311
+ import type { ServiceOrder } from '../service/order.ts';
1312
+ import type { ServiceStockAudit } from '../service/stockAudit.ts';
1313
+ import type { ServiceStockBalance } from '../service/stockBalance.ts';
1314
+ export interface IModuleService {
1315
+ 'cart': ServiceCart;
1316
+ 'order': ServiceOrder;
1317
+ 'stockAudit': ServiceStockAudit;
1318
+ 'stockBalance': ServiceStockBalance;
1319
+ }
1320
+ /** service: end */
1321
+ /** service: begin */
1322
+
1323
+ import 'vona';
1324
+ declare module 'vona' {
1325
+ export interface IBeanRecordGeneral {
1326
+ 'commerce-trade.service.cart': ServiceCart;
1327
+ 'commerce-trade.service.order': ServiceOrder;
1328
+ 'commerce-trade.service.stockAudit': ServiceStockAudit;
1329
+ 'commerce-trade.service.stockBalance': ServiceStockBalance;
1330
+ }
1331
+ }
1332
+ /** service: end */
1333
+ /** meta: begin */
1334
+ export * from '../bean/meta.index.ts';
1335
+ export * from '../bean/meta.version.ts';
1336
+ import type { IMetaOptionsIndex } from 'vona-module-a-index';
1337
+ import 'vona-module-a-meta';
1338
+ declare module 'vona-module-a-meta' {
1339
+
1340
+ export interface IMetaRecord {
1341
+ 'commerce-trade:index': IMetaOptionsIndex;
1342
+ 'commerce-trade:version': never;
1343
+ }
1344
+
1345
+
1346
+ }
1347
+ declare module 'vona-module-commerce-trade' {
1348
+
1349
+ export interface MetaIndex {
1350
+ /** @internal */
1351
+ get scope(): ScopeModuleCommerceTrade;
1352
+ }
1353
+
1354
+ export interface MetaIndex {
1355
+ get $beanFullName(): 'commerce-trade.meta.index';
1356
+ get $onionName(): 'commerce-trade:index';
1357
+ get $onionOptions(): IMetaOptionsIndex;
1358
+ }
1359
+
1360
+ export interface MetaVersion {
1361
+ /** @internal */
1362
+ get scope(): ScopeModuleCommerceTrade;
1363
+ }
1364
+
1365
+ export interface MetaVersion {
1366
+ get $beanFullName(): 'commerce-trade.meta.version';
1367
+ get $onionName(): 'commerce-trade:version';
1368
+ }
1369
+ }
1370
+ /** meta: end */
1371
1371
  /** ssrMenu: begin */
1372
1372
  export * from '../bean/ssrMenu.order.ts';
1373
1373
  export * from '../bean/ssrMenu.stockAudit.ts';