cabloy 5.1.240 → 5.1.241

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 (42) hide show
  1. package/.cabloy-version +1 -1
  2. package/CHANGELOG.md +12 -0
  3. package/package.json +1 -1
  4. package/repo-docs/backend/openapi-guide.md +18 -0
  5. package/repo-e2e/specs/home-user-account.spec.ts +53 -8
  6. package/vona/packages-vona/vona/package.json +1 -1
  7. package/vona/pnpm-lock.yaml +16 -141
  8. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/dto/operatorContext.ts +4 -1
  9. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/service/operator.ts +1 -0
  10. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/test/operatorAccess.test.ts +1 -0
  11. package/vona/src/suite/a-home/modules/home-user/src/bean/meta.version.ts +1 -0
  12. package/vona/src/suite/a-home/modules/home-user/src/controller/passport.ts +1 -0
  13. package/vona/src/suite/a-home/modules/home-user/src/dto/accountCurrent.ts +3 -0
  14. package/vona/src/suite/a-home/modules/home-user/src/dto/accountProfileUpdate.ts +9 -2
  15. package/vona/src/suite/a-home/modules/home-user/src/dto/passportUser.ts +3 -0
  16. package/vona/src/suite/a-home/modules/home-user/src/entity/user.ts +3 -0
  17. package/vona/src/suite/a-home/modules/home-user/src/service/account.ts +7 -3
  18. package/vona/src/suite/a-home/modules/home-user/src/service/userAdapter.ts +1 -0
  19. package/vona/src/suite/a-home/modules/home-user/test/account.test.ts +133 -8
  20. package/vona/src/suite/a-home/modules/home-user/test/accountOpenapi.test.ts +32 -5
  21. package/vona/src/suite/a-home/modules/home-user/test/passport.test.ts +159 -1
  22. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/package.json +1 -1
  23. package/vona/src/suite-vendor/a-cabloy/package.json +2 -2
  24. package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
  25. package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/bean.permission.ts +54 -8
  26. package/vona/src/suite-vendor/a-vona/modules/a-permission/test/permission.test.ts +228 -16
  27. package/vona/src/suite-vendor/a-vona/modules/a-user/package.json +1 -1
  28. package/vona/src/suite-vendor/a-vona/modules/a-user/src/types/user.ts +1 -0
  29. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  30. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/schemas.ts +68 -52
  31. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/types.ts +530 -344
  32. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/page/dashboard/controller.tsx +7 -1
  33. package/zova/src/suite/a-home/modules/home-api/src/api/openapi/types.ts +6 -1
  34. package/zova/src/suite/a-home/modules/home-base/src/config/locale/en-us.ts +1 -0
  35. package/zova/src/suite/a-home/modules/home-base/src/config/locale/zh-cn.ts +1 -0
  36. package/zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/render.user.tsx +1 -1
  37. package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.user.tsx +3 -1
  38. package/zova/src/suite/a-home/modules/home-passport/src/model/passport.ts +4 -0
  39. package/zova/src/suite/a-home/modules/home-user/src/config/locale/en-us.ts +1 -0
  40. package/zova/src/suite/a-home/modules/home-user/src/config/locale/zh-cn.ts +1 -0
  41. package/zova/src/suite/a-home/modules/home-user/src/model/account.ts +2 -1
  42. package/zova/src/suite/a-home/modules/home-user/src/page/account/controller.tsx +17 -3
@@ -1,10 +1,14 @@
1
+ import type { VonaContext } from 'vona';
1
2
  import type { ICachingActionKeyInfo } from 'vona-module-a-caching';
2
3
  import type { IRbacPolicyDecision } from 'vona-module-a-rbac';
4
+ import type { ContextRoute } from 'vona-module-a-web';
3
5
 
4
6
  import assert from 'node:assert';
5
7
  import { describe, it } from 'node:test';
6
- import { beanFullNameFromOnionName } from 'vona';
8
+ import { appResource, beanFullNameFromOnionName } from 'vona';
9
+ import { app } from 'vona-mock';
7
10
  import { getRbacDecision, setRbacDecision, SymbolRbacDecision } from 'vona-module-a-rbac';
11
+ import { getCacheControllerRoutes, recordResourceNameToRoutePath } from 'vona-module-a-web';
8
12
 
9
13
  import { BeanPermission } from '../src/bean/bean.permission.ts';
10
14
 
@@ -51,6 +55,64 @@ function createCachePermission(clearedCacheNames: string[]) {
51
55
  return permission;
52
56
  }
53
57
 
58
+ const BeanFullNameGuardRbac = beanFullNameFromOnionName('a-rbac:rbac', 'guard');
59
+ const GuardResource = 'test-rest:product';
60
+
61
+ async function withGuardPermission(
62
+ guard: (ctx: VonaContext) => Promise<boolean | void>,
63
+ callback: (fixture: {
64
+ permission: BeanPermission;
65
+ ctx: VonaContext;
66
+ passport: { isAuthenticated: boolean; isAccountActive: boolean; isActivated: boolean };
67
+ action: IRbacPolicyDecision['action'];
68
+ }) => Promise<void>,
69
+ rbac = false,
70
+ ) {
71
+ await app.bean.executor.mockCtx(async () => {
72
+ const controller = recordResourceNameToRoutePath[GuardResource].controller;
73
+ const controllerBeanFullName = appResource.getBean(controller)!.beanFullName;
74
+ const route = {
75
+ controller,
76
+ controllerBeanFullName,
77
+ action: 'create',
78
+ route: { meta: rbac ? { [BeanFullNameGuardRbac]: {} } : {} },
79
+ } as ContextRoute;
80
+ const action: IRbacPolicyDecision['action'] = {
81
+ actionKey: `${controllerBeanFullName}#create`,
82
+ actionInheritKey: `${controllerBeanFullName}#update`,
83
+ controllerBeanFullName,
84
+ action: 'create',
85
+ route,
86
+ options: {},
87
+ };
88
+ const unexpected = () =>
89
+ assert.fail('guard-only checks must not use permission retrieval or scope projection');
90
+ const fixtureApp = {
91
+ meta: {},
92
+ bean: { onion: { guard: { compose: () => guard } } },
93
+ };
94
+ getCacheControllerRoutes(fixtureApp as never)[controllerBeanFullName] = [route];
95
+ const passport = { isAuthenticated: true, isAccountActive: true, isActivated: true };
96
+ const permission = Object.create(BeanPermission.prototype) as BeanPermission;
97
+ Object.defineProperties(permission, {
98
+ app: { value: fixtureApp },
99
+ ctx: { value: app.ctx },
100
+ bean: {
101
+ value: {
102
+ passport,
103
+ rbacCatalog: { getAction: () => action },
104
+ rbacScope: { current: unexpected },
105
+ },
106
+ },
107
+ scope: { value: { event: { retrievePermissionAction: { emit: unexpected } } } },
108
+ retrievePermissionAction: { value: unexpected },
109
+ retrievePermissionActionByRoles: { value: unexpected },
110
+ retrievePermissionActionByUser: { value: unexpected },
111
+ });
112
+ await callback({ permission, ctx: app.ctx, passport, action });
113
+ });
114
+ }
115
+
54
116
  describe('permission.test.ts', { concurrency: false }, () => {
55
117
  it('normalizes role cache keys by role identity', () => {
56
118
  const first = createPermission({
@@ -62,10 +124,10 @@ describe('permission.test.ts', { concurrency: false }, () => {
62
124
  roleIds: ['role-a', 'role-b'],
63
125
  });
64
126
 
65
- const info = cacheInfo('training-student:student', 'select');
127
+ const info = cacheInfo('test:resource', 'select');
66
128
  assert.equal(
67
129
  (first as any).retrievePermissionActionByRolesCacheKey(info),
68
- 'action:training-student:student:select:roles:role-a,role-b',
130
+ 'action:test:resource:select:roles:role-a,role-b',
69
131
  );
70
132
  assert.equal(
71
133
  (first as any).retrievePermissionActionByRolesCacheKey(info),
@@ -78,7 +140,7 @@ describe('permission.test.ts', { concurrency: false }, () => {
78
140
  userId: 'user-1',
79
141
  roleIds: ['role-a'],
80
142
  });
81
- const info = cacheInfo('training-student:student', 'select');
143
+ const info = cacheInfo('test:resource', 'select');
82
144
 
83
145
  assert.notEqual(
84
146
  (permission as any).retrievePermissionActionByRolesCacheKey(info),
@@ -100,10 +162,10 @@ describe('permission.test.ts', { concurrency: false }, () => {
100
162
  roleIds: ['role-b'],
101
163
  });
102
164
 
103
- const info = cacheInfo('training-student:student', 'select');
165
+ const info = cacheInfo('test:resource', 'select');
104
166
  assert.equal(
105
167
  (first as any).retrievePermissionActionByUserCacheKey(info),
106
- 'action:training-student:student:select:user:user-1:roles:role-a',
168
+ 'action:test:resource:select:user:user-1:roles:role-a',
107
169
  );
108
170
  assert.notEqual(
109
171
  (first as any).retrievePermissionActionByUserCacheKey(info),
@@ -152,24 +214,21 @@ describe('permission.test.ts', { concurrency: false }, () => {
152
214
  });
153
215
 
154
216
  assert.equal(
155
- await permission.retrievePermissionAction('training-student:student', 'ordinary'),
217
+ await permission.retrievePermissionAction('test:resource' as never, 'ordinary'),
156
218
  false,
157
219
  );
158
- assert.equal(
159
- await permission.retrievePermissionAction('training-student:student', 'rbac'),
160
- true,
161
- );
220
+ assert.equal(await permission.retrievePermissionAction('test:resource' as never, 'rbac'), true);
162
221
  assert.deepEqual(calls, ['roles', 'user']);
163
222
  });
164
223
 
165
224
  it('isolates resource permission snapshots by user', () => {
166
225
  const first = createPermission({ userId: 'user-1' });
167
226
  const otherUser = createPermission({ userId: 'user-2' });
168
- const info = cacheInfo('training-student:student');
227
+ const info = cacheInfo('test:resource');
169
228
 
170
229
  assert.equal(
171
230
  (first as any).retrievePermissionsCacheKey(info),
172
- 'user:training-student:student:user:user-1',
231
+ 'user:test:resource:user:user-1',
173
232
  );
174
233
  assert.notEqual(
175
234
  (first as any).retrievePermissionsCacheKey(info),
@@ -307,6 +366,159 @@ describe('permission.test.ts', { concurrency: false }, () => {
307
366
  assert.equal(ctx.innerAccess, true);
308
367
  });
309
368
 
369
+ it('checks current guards without permission events, result caches, or projection', async () => {
370
+ let allowed = true;
371
+ let calls = 0;
372
+ await withGuardPermission(
373
+ async () => {
374
+ calls++;
375
+ return allowed;
376
+ },
377
+ async ({ permission }) => {
378
+ assert.equal(await permission.checkPermissionActionGuards(GuardResource, 'create'), true);
379
+ allowed = false;
380
+ assert.equal(await permission.checkPermissionActionGuards(GuardResource, 'create'), false);
381
+ assert.equal(calls, 2);
382
+ },
383
+ );
384
+ });
385
+
386
+ it('fails closed before guards for unknown routes and Passport admission failures', async () => {
387
+ await withGuardPermission(
388
+ async () => assert.fail('guards must not run before admission'),
389
+ async ({ permission, passport }) => {
390
+ assert.equal(
391
+ await permission.checkPermissionActionGuards('test:missing' as never, 'create'),
392
+ false,
393
+ );
394
+ assert.equal(await permission.checkPermissionActionGuards(GuardResource, 'missing'), false);
395
+ passport.isAuthenticated = false;
396
+ assert.equal(await permission.checkPermissionActionGuards(GuardResource, 'create'), false);
397
+ },
398
+ );
399
+ });
400
+
401
+ it('converts guard authorization errors to false and propagates unexpected errors', async () => {
402
+ let failure: Error;
403
+ await withGuardPermission(
404
+ async () => {
405
+ throw failure;
406
+ },
407
+ async ({ permission }) => {
408
+ for (const code of [401, 403]) {
409
+ failure = Object.assign(new Error('authorization failure'), { code });
410
+ assert.equal(
411
+ await permission.checkPermissionActionGuards(GuardResource, 'create'),
412
+ false,
413
+ );
414
+ }
415
+ failure = new Error('unexpected guard failure');
416
+ await assert.rejects(
417
+ () => permission.checkPermissionActionGuards(GuardResource, 'create'),
418
+ failure,
419
+ );
420
+ },
421
+ );
422
+ });
423
+
424
+ it('requires a fresh allowed RBAC decision matching the full catalog action identity', async () => {
425
+ let decision: IRbacPolicyDecision | undefined;
426
+ await withGuardPermission(
427
+ async ctx => {
428
+ assert.equal(getRbacDecision(ctx), undefined);
429
+ if (decision) setRbacDecision(ctx, decision);
430
+ return true;
431
+ },
432
+ async ({ permission, ctx, action }) => {
433
+ const valid: IRbacPolicyDecision = {
434
+ allowed: true,
435
+ actionKey: action.actionKey,
436
+ action: { ...action },
437
+ terms: [{ dataScope: 'all' }],
438
+ };
439
+ setRbacDecision(ctx, valid);
440
+ assert.equal(await permission.checkPermissionActionGuards(GuardResource, 'create'), false);
441
+ assert.equal(getRbacDecision(ctx), valid);
442
+ for (const invalid of [
443
+ { ...valid, allowed: false },
444
+ { ...valid, actionKey: 'other#action' },
445
+ ...[
446
+ { actionKey: 'other#action' },
447
+ { actionInheritKey: undefined },
448
+ { controllerBeanFullName: 'other.controller' },
449
+ { action: 'other' },
450
+ ].map(mismatch => ({ ...valid, action: { ...action, ...mismatch } })),
451
+ ]) {
452
+ decision = invalid;
453
+ assert.equal(
454
+ await permission.checkPermissionActionGuards(GuardResource, 'create'),
455
+ false,
456
+ );
457
+ assert.equal(getRbacDecision(ctx), valid);
458
+ }
459
+ decision = valid;
460
+ assert.equal(await permission.checkPermissionActionGuards(GuardResource, 'create'), true);
461
+ assert.equal(getRbacDecision(ctx), valid);
462
+ delete ctx[SymbolRbacDecision];
463
+ assert.equal(await permission.checkPermissionActionGuards(GuardResource, 'create'), true);
464
+ assert.equal(Object.hasOwn(ctx, SymbolRbacDecision), false);
465
+ },
466
+ true,
467
+ );
468
+ });
469
+
470
+ it('restores property descriptors and inherited innerAccess after success and failure', async () => {
471
+ let failure: Error | undefined;
472
+ await withGuardPermission(
473
+ async ctx => {
474
+ assert.equal(ctx.route.action, 'create');
475
+ assert.equal(ctx.innerAccess, false);
476
+ assert.equal(getRbacDecision(ctx), undefined);
477
+ if (failure) throw failure;
478
+ return true;
479
+ },
480
+ async ({ permission, ctx, action }) => {
481
+ assert.equal(Object.hasOwn(ctx, 'innerAccess'), false);
482
+ ctx.innerAccess = true;
483
+ Object.defineProperty(ctx, 'route', {
484
+ value: { action: 'previous' },
485
+ writable: true,
486
+ configurable: true,
487
+ enumerable: false,
488
+ });
489
+ Object.defineProperty(ctx, SymbolRbacDecision, {
490
+ value: {
491
+ allowed: true,
492
+ actionKey: action.actionKey,
493
+ action,
494
+ terms: [{ dataScope: 'all' }],
495
+ },
496
+ writable: true,
497
+ configurable: true,
498
+ enumerable: false,
499
+ });
500
+ const descriptors = Object.getOwnPropertyDescriptors(ctx);
501
+ assert.equal(await permission.checkPermissionActionGuards(GuardResource, 'create'), true);
502
+ assert.deepEqual(Object.getOwnPropertyDescriptors(ctx), descriptors);
503
+ assert.equal(ctx.innerAccess, true);
504
+ failure = new Error('guard failure');
505
+ await assert.rejects(
506
+ () => permission.checkPermissionActionGuards(GuardResource, 'create'),
507
+ failure,
508
+ );
509
+ assert.deepEqual(Object.getOwnPropertyDescriptors(ctx), descriptors);
510
+ assert.equal(ctx.innerAccess, true);
511
+
512
+ delete (ctx as any).route;
513
+ delete ctx[SymbolRbacDecision];
514
+ const absentDescriptors = Object.getOwnPropertyDescriptors(ctx);
515
+ failure = undefined;
516
+ assert.equal(await permission.checkPermissionActionGuards(GuardResource, 'create'), true);
517
+ assert.deepEqual(Object.getOwnPropertyDescriptors(ctx), absentDescriptors);
518
+ },
519
+ );
520
+ });
521
+
310
522
  it('reduces an RBAC action projection to its final boolean result', async () => {
311
523
  const allowed = createPermission({});
312
524
  const denied = createPermission({});
@@ -333,8 +545,8 @@ describe('permission.test.ts', { concurrency: false }, () => {
333
545
  retrievePermissionAction: { value: async () => true },
334
546
  });
335
547
 
336
- assert.equal(await allowed.checkPermissionAction('training-student:student', 'select'), true);
337
- assert.equal(await denied.checkPermissionAction('training-student:student', 'select'), false);
338
- assert.equal(await legacy.checkPermissionAction('training-student:student', 'select'), true);
548
+ assert.equal(await allowed.checkPermissionAction('test:resource' as never, 'select'), true);
549
+ assert.equal(await denied.checkPermissionAction('test:resource' as never, 'select'), false);
550
+ assert.equal(await legacy.checkPermissionAction('test:resource' as never, 'select'), true);
339
551
  });
340
552
  });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-a-user",
3
- "version": "5.1.25",
3
+ "version": "5.1.26",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "keywords": [
@@ -16,6 +16,7 @@ export interface IUserIdRecord {
16
16
  export interface IUser {
17
17
  id: TableIdentity;
18
18
  name: string;
19
+ displayName?: string;
19
20
  avatar?: string;
20
21
  email?: string;
21
22
  mobile?: string;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-suite-a-vona",
3
- "version": "5.1.110",
3
+ "version": "5.1.111",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "author": "",
@@ -6,6 +6,42 @@ export type ApiSchemaTestVonaDtoUserCreate = components['schemas']['test-vona.dt
6
6
  export type ApiSchemaTestVonaDtoUserCreatePartial = Partial<ApiSchemaTestVonaDtoUserCreate>;
7
7
  export type ApiSchemaTestVonaEntityProduct = components['schemas']['test-vona.entity.product'];
8
8
  export type ApiSchemaTestVonaEntityProductPartial = Partial<ApiSchemaTestVonaEntityProduct>;
9
+ export type ApiSchemaAImageDtoImageUploadPolicyResponse =
10
+ components['schemas']['a-image.dto.imageUploadPolicyResponse'];
11
+ export type ApiSchemaAImageDtoImageUploadPolicyResponsePartial =
12
+ Partial<ApiSchemaAImageDtoImageUploadPolicyResponse>;
13
+ export type ApiSchemaAImageDtoImageUploadPolicyRequest =
14
+ components['schemas']['a-image.dto.imageUploadPolicyRequest'];
15
+ export type ApiSchemaAImageDtoImageUploadPolicyRequestPartial =
16
+ Partial<ApiSchemaAImageDtoImageUploadPolicyRequest>;
17
+ export type ApiSchemaAImageDtoImageUploadResponse =
18
+ components['schemas']['a-image.dto.imageUploadResponse'];
19
+ export type ApiSchemaAImageDtoImageUploadResponsePartial =
20
+ Partial<ApiSchemaAImageDtoImageUploadResponse>;
21
+ export type ApiSchemaAImageDtoImageDirectUploadResponse =
22
+ components['schemas']['a-image.dto.imageDirectUploadResponse'];
23
+ export type ApiSchemaAImageDtoImageDirectUploadResponsePartial =
24
+ Partial<ApiSchemaAImageDtoImageDirectUploadResponse>;
25
+ export type ApiSchemaAImageDtoImageDirectUploadRequest =
26
+ components['schemas']['a-image.dto.imageDirectUploadRequest'];
27
+ export type ApiSchemaAImageDtoImageDirectUploadRequestPartial =
28
+ Partial<ApiSchemaAImageDtoImageDirectUploadRequest>;
29
+ export type ApiSchemaAImageDtoImageDirectUploadFinalizeResponse =
30
+ components['schemas']['a-image.dto.imageDirectUploadFinalizeResponse'];
31
+ export type ApiSchemaAImageDtoImageDirectUploadFinalizeResponsePartial =
32
+ Partial<ApiSchemaAImageDtoImageDirectUploadFinalizeResponse>;
33
+ export type ApiSchemaAImageDtoImageDirectUploadFinalizeRequest =
34
+ components['schemas']['a-image.dto.imageDirectUploadFinalizeRequest'];
35
+ export type ApiSchemaAImageDtoImageDirectUploadFinalizeRequestPartial =
36
+ Partial<ApiSchemaAImageDtoImageDirectUploadFinalizeRequest>;
37
+ export type ApiSchemaAImageDtoImageUploadUrlRequest =
38
+ components['schemas']['a-image.dto.imageUploadUrlRequest'];
39
+ export type ApiSchemaAImageDtoImageUploadUrlRequestPartial =
40
+ Partial<ApiSchemaAImageDtoImageUploadUrlRequest>;
41
+ export type ApiSchemaAImageDtoImageTransformOptions_2d063d28bc7243bed02ebd8bddf1212a93c6305b =
42
+ components['schemas']['a-image.dto.imageTransformOptions_2d063d28bc7243bed02ebd8bddf1212a93c6305b'];
43
+ export type ApiSchemaAImageDtoImageTransformOptions_2d063d28bc7243bed02ebd8bddf1212a93c6305bPartial =
44
+ Partial<ApiSchemaAImageDtoImageTransformOptions_2d063d28bc7243bed02ebd8bddf1212a93c6305b>;
9
45
  export type ApiSchemaACaptchaDtoCaptchaData = components['schemas']['a-captcha.dto.captchaData'];
10
46
  export type ApiSchemaACaptchaDtoCaptchaDataPartial = Partial<ApiSchemaACaptchaDtoCaptchaData>;
11
47
  export type ApiSchemaAPayDtoPaymentSessionView =
@@ -43,42 +79,6 @@ export type ApiSchemaCommerceMemberDtoAddressView_2d063d28bc7243bed02ebd8bddf121
43
79
  components['schemas']['commerce-member.dto.addressView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_425dbecccd52e19e24888f99e1b1670233afa875'];
44
80
  export type ApiSchemaCommerceMemberDtoAddressView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_425dbecccd52e19e24888f99e1b1670233afa875Partial =
45
81
  Partial<ApiSchemaCommerceMemberDtoAddressView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_425dbecccd52e19e24888f99e1b1670233afa875>;
46
- export type ApiSchemaAImageDtoImageUploadPolicyResponse =
47
- components['schemas']['a-image.dto.imageUploadPolicyResponse'];
48
- export type ApiSchemaAImageDtoImageUploadPolicyResponsePartial =
49
- Partial<ApiSchemaAImageDtoImageUploadPolicyResponse>;
50
- export type ApiSchemaAImageDtoImageUploadPolicyRequest =
51
- components['schemas']['a-image.dto.imageUploadPolicyRequest'];
52
- export type ApiSchemaAImageDtoImageUploadPolicyRequestPartial =
53
- Partial<ApiSchemaAImageDtoImageUploadPolicyRequest>;
54
- export type ApiSchemaAImageDtoImageUploadResponse =
55
- components['schemas']['a-image.dto.imageUploadResponse'];
56
- export type ApiSchemaAImageDtoImageUploadResponsePartial =
57
- Partial<ApiSchemaAImageDtoImageUploadResponse>;
58
- export type ApiSchemaAImageDtoImageDirectUploadResponse =
59
- components['schemas']['a-image.dto.imageDirectUploadResponse'];
60
- export type ApiSchemaAImageDtoImageDirectUploadResponsePartial =
61
- Partial<ApiSchemaAImageDtoImageDirectUploadResponse>;
62
- export type ApiSchemaAImageDtoImageDirectUploadRequest =
63
- components['schemas']['a-image.dto.imageDirectUploadRequest'];
64
- export type ApiSchemaAImageDtoImageDirectUploadRequestPartial =
65
- Partial<ApiSchemaAImageDtoImageDirectUploadRequest>;
66
- export type ApiSchemaAImageDtoImageDirectUploadFinalizeResponse =
67
- components['schemas']['a-image.dto.imageDirectUploadFinalizeResponse'];
68
- export type ApiSchemaAImageDtoImageDirectUploadFinalizeResponsePartial =
69
- Partial<ApiSchemaAImageDtoImageDirectUploadFinalizeResponse>;
70
- export type ApiSchemaAImageDtoImageDirectUploadFinalizeRequest =
71
- components['schemas']['a-image.dto.imageDirectUploadFinalizeRequest'];
72
- export type ApiSchemaAImageDtoImageDirectUploadFinalizeRequestPartial =
73
- Partial<ApiSchemaAImageDtoImageDirectUploadFinalizeRequest>;
74
- export type ApiSchemaAImageDtoImageUploadUrlRequest =
75
- components['schemas']['a-image.dto.imageUploadUrlRequest'];
76
- export type ApiSchemaAImageDtoImageUploadUrlRequestPartial =
77
- Partial<ApiSchemaAImageDtoImageUploadUrlRequest>;
78
- export type ApiSchemaAImageDtoImageTransformOptions_2d063d28bc7243bed02ebd8bddf1212a93c6305b =
79
- components['schemas']['a-image.dto.imageTransformOptions_2d063d28bc7243bed02ebd8bddf1212a93c6305b'];
80
- export type ApiSchemaAImageDtoImageTransformOptions_2d063d28bc7243bed02ebd8bddf1212a93c6305bPartial =
81
- Partial<ApiSchemaAImageDtoImageTransformOptions_2d063d28bc7243bed02ebd8bddf1212a93c6305b>;
82
82
  export type ApiSchemaHomeUserDtoAccountCurrent =
83
83
  components['schemas']['home-user.dto.accountCurrent'];
84
84
  export type ApiSchemaHomeUserDtoAccountCurrentPartial = Partial<ApiSchemaHomeUserDtoAccountCurrent>;
@@ -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 =
@@ -366,10 +366,10 @@ export type ApiSchemaCommerceCatalogDtoProductPublicDetail_2d063d28bc7243bed02eb
366
366
  components['schemas']['commerce-catalog.dto.productPublicDetail_2d063d28bc7243bed02ebd8bddf1212a93c6305b'];
367
367
  export type ApiSchemaCommerceCatalogDtoProductPublicDetail_2d063d28bc7243bed02ebd8bddf1212a93c6305bPartial =
368
368
  Partial<ApiSchemaCommerceCatalogDtoProductPublicDetail_2d063d28bc7243bed02ebd8bddf1212a93c6305b>;
369
- export type ApiSchemaCommerceCatalogDtoProductView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_9a6ea970b2f00d574b88030d8c96cbf7b1e699d7 =
370
- components['schemas']['commerce-catalog.dto.productView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_9a6ea970b2f00d574b88030d8c96cbf7b1e699d7'];
371
- export type ApiSchemaCommerceCatalogDtoProductView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_9a6ea970b2f00d574b88030d8c96cbf7b1e699d7Partial =
372
- Partial<ApiSchemaCommerceCatalogDtoProductView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_9a6ea970b2f00d574b88030d8c96cbf7b1e699d7>;
369
+ export type ApiSchemaCommerceCatalogDtoProductView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_a2f92cabb46b0630848b50414c0d4c60efb47a57 =
370
+ components['schemas']['commerce-catalog.dto.productView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_a2f92cabb46b0630848b50414c0d4c60efb47a57'];
371
+ export type ApiSchemaCommerceCatalogDtoProductView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_a2f92cabb46b0630848b50414c0d4c60efb47a57Partial =
372
+ Partial<ApiSchemaCommerceCatalogDtoProductView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_a2f92cabb46b0630848b50414c0d4c60efb47a57>;
373
373
  export type ApiSchemaCommerceCatalogDtoProductUpdate =
374
374
  components['schemas']['commerce-catalog.dto.productUpdate'];
375
375
  export type ApiSchemaCommerceCatalogDtoProductUpdatePartial =
@@ -435,10 +435,10 @@ export type ApiSchemaAImageDtoImageView = components['schemas']['a-image.dto.ima
435
435
  export type ApiSchemaAImageDtoImageViewPartial = Partial<ApiSchemaAImageDtoImageView>;
436
436
  export type ApiSchemaAFileDtoFileView = components['schemas']['a-file.dto.fileView'];
437
437
  export type ApiSchemaAFileDtoFileViewPartial = Partial<ApiSchemaAFileDtoFileView>;
438
- export type ApiSchemaTrainingRecordDtoRecordView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_425dbecccd52e19e24888f99e1b1670233afa875 =
439
- components['schemas']['training-record.dto.recordView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_425dbecccd52e19e24888f99e1b1670233afa875'];
440
- export type ApiSchemaTrainingRecordDtoRecordView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_425dbecccd52e19e24888f99e1b1670233afa875Partial =
441
- Partial<ApiSchemaTrainingRecordDtoRecordView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_425dbecccd52e19e24888f99e1b1670233afa875>;
438
+ export type ApiSchemaTrainingRecordDtoRecordView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_7d715789d9643740a04e8a6c0f6fb951884bc347 =
439
+ components['schemas']['training-record.dto.recordView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_7d715789d9643740a04e8a6c0f6fb951884bc347'];
440
+ export type ApiSchemaTrainingRecordDtoRecordView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_7d715789d9643740a04e8a6c0f6fb951884bc347Partial =
441
+ Partial<ApiSchemaTrainingRecordDtoRecordView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_7d715789d9643740a04e8a6c0f6fb951884bc347>;
442
442
  export type ApiSchemaTrainingRecordDtoRecordUpdate =
443
443
  components['schemas']['training-record.dto.recordUpdate'];
444
444
  export type ApiSchemaTrainingRecordDtoRecordUpdatePartial =
@@ -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_4e7e5941f704425ce1be04de1885c36427ccc436 =
467
- components['schemas']['training-student.dto.studentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_4e7e5941f704425ce1be04de1885c36427ccc436'];
468
- export type ApiSchemaTrainingStudentDtoStudentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_4e7e5941f704425ce1be04de1885c36427ccc436Partial =
469
- Partial<ApiSchemaTrainingStudentDtoStudentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_4e7e5941f704425ce1be04de1885c36427ccc436>;
466
+ export type ApiSchemaTrainingStudentDtoStudentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_4826fc678e47603ec467782ddb0d02463792cd60 =
467
+ components['schemas']['training-student.dto.studentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_4826fc678e47603ec467782ddb0d02463792cd60'];
468
+ export type ApiSchemaTrainingStudentDtoStudentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_4826fc678e47603ec467782ddb0d02463792cd60Partial =
469
+ Partial<ApiSchemaTrainingStudentDtoStudentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_4826fc678e47603ec467782ddb0d02463792cd60>;
470
470
  export type ApiSchemaTrainingStudentDtoStudentUpdate =
471
471
  components['schemas']['training-student.dto.studentUpdate'];
472
472
  export type ApiSchemaTrainingStudentDtoStudentUpdatePartial =
@@ -475,6 +475,10 @@ export type ApiSchemaTrainingStudentDtoStudentSummary_2d063d28bc7243bed02ebd8bdd
475
475
  components['schemas']['training-student.dto.studentSummary_2d063d28bc7243bed02ebd8bddf1212a93c6305b'];
476
476
  export type ApiSchemaTrainingStudentDtoStudentSummary_2d063d28bc7243bed02ebd8bddf1212a93c6305bPartial =
477
477
  Partial<ApiSchemaTrainingStudentDtoStudentSummary_2d063d28bc7243bed02ebd8bddf1212a93c6305b>;
478
+ export type ApiSchemaTrainingStudentDtoStudentDeleteBulk =
479
+ components['schemas']['training-student.dto.studentDeleteBulk'];
480
+ export type ApiSchemaTrainingStudentDtoStudentDeleteBulkPartial =
481
+ Partial<ApiSchemaTrainingStudentDtoStudentDeleteBulk>;
478
482
  export type ApiSchemaBasicMetricsDtoMetricsSnapshot =
479
483
  components['schemas']['basic-metrics.dto.metricsSnapshot'];
480
484
  export type ApiSchemaBasicMetricsDtoMetricsSnapshotPartial =
@@ -487,6 +491,18 @@ export type ApiSchemaBasicMetricsDtoMetricsQueue =
487
491
  components['schemas']['basic-metrics.dto.metricsQueue'];
488
492
  export type ApiSchemaBasicMetricsDtoMetricsQueuePartial =
489
493
  Partial<ApiSchemaBasicMetricsDtoMetricsQueue>;
494
+ export type ApiSchemaALayoutprofileDtoLayoutProfile_2d063d28bc7243bed02ebd8bddf1212a93c6305b =
495
+ components['schemas']['a-layoutprofile.dto.layoutProfile_2d063d28bc7243bed02ebd8bddf1212a93c6305b'];
496
+ export type ApiSchemaALayoutprofileDtoLayoutProfile_2d063d28bc7243bed02ebd8bddf1212a93c6305bPartial =
497
+ Partial<ApiSchemaALayoutprofileDtoLayoutProfile_2d063d28bc7243bed02ebd8bddf1212a93c6305b>;
498
+ export type ApiSchemaALayoutprofileDtoLayoutProfile =
499
+ components['schemas']['a-layoutprofile.dto.layoutProfile'];
500
+ export type ApiSchemaALayoutprofileDtoLayoutProfilePartial =
501
+ Partial<ApiSchemaALayoutprofileDtoLayoutProfile>;
502
+ export type ApiSchemaALayoutprofileDtoLayoutProfileSave =
503
+ components['schemas']['a-layoutprofile.dto.layoutProfileSave'];
504
+ export type ApiSchemaALayoutprofileDtoLayoutProfileSavePartial =
505
+ Partial<ApiSchemaALayoutprofileDtoLayoutProfileSave>;
490
506
  export type ApiSchemaAFileDtoFileUploadPolicyResponse =
491
507
  components['schemas']['a-file.dto.fileUploadPolicyResponse'];
492
508
  export type ApiSchemaAFileDtoFileUploadPolicyResponsePartial =