@fiado/type-kit 3.502.0 → 3.503.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_test_/unit/platformRbac/dtos/CreateTenantUserRequest.test.ts +31 -0
- package/_test_/unit/retailIntegration/applyRetailEventRequest.test.ts +11 -0
- package/_test_/unit/retailIntegration/eventPayloads.test.ts +124 -0
- package/_test_/unit/retailIntegration/payloadValidators.test.ts +34 -0
- package/_test_/unit/retailIntegration/retailSystemEnums.test.ts +18 -0
- package/_test_/unit/retailOrg/dtos/Store.test.ts +6 -0
- package/bin/platformRbac/dtos/CreateTenantUserRequest.d.ts +6 -4
- package/bin/platformRbac/dtos/CreateTenantUserRequest.js +11 -1
- package/bin/platformRbac/validators/SuppressInvitationRequiredWithoutRole.d.ts +6 -0
- package/bin/platformRbac/validators/SuppressInvitationRequiredWithoutRole.js +24 -0
- package/bin/retailIntegration/constants/retailIntegrationLimits.d.ts +13 -0
- package/bin/retailIntegration/constants/retailIntegrationLimits.js +14 -1
- package/bin/retailIntegration/dtos/ApplyRetailEventRequest.d.ts +8 -0
- package/bin/retailIntegration/dtos/ApplyRetailEventRequest.js +20 -0
- package/bin/retailIntegration/dtos/InventoryEventPayload.d.ts +25 -0
- package/bin/retailIntegration/dtos/InventoryEventPayload.js +94 -0
- package/bin/retailIntegration/dtos/ProductEventPayload.d.ts +25 -0
- package/bin/retailIntegration/dtos/ProductEventPayload.js +113 -0
- package/bin/retailIntegration/dtos/RetailUserEventPayload.d.ts +12 -0
- package/bin/retailIntegration/dtos/RetailUserEventPayload.js +58 -0
- package/bin/retailIntegration/dtos/StoreEventPayload.d.ts +30 -0
- package/bin/retailIntegration/dtos/StoreEventPayload.js +137 -0
- package/bin/retailIntegration/enums/RetailEventRejectCodeEnum.d.ts +16 -0
- package/bin/retailIntegration/enums/RetailEventRejectCodeEnum.js +20 -0
- package/bin/retailIntegration/enums/RetailMovementTypeEnum.d.ts +10 -0
- package/bin/retailIntegration/enums/RetailMovementTypeEnum.js +14 -0
- package/bin/retailIntegration/enums/index.d.ts +2 -0
- package/bin/retailIntegration/enums/index.js +2 -0
- package/bin/retailIntegration/index.d.ts +5 -0
- package/bin/retailIntegration/index.js +5 -0
- package/bin/retailIntegration/validators/payloadValidators.d.ts +18 -0
- package/bin/retailIntegration/validators/payloadValidators.js +72 -0
- package/bin/retailOrg/dtos/Store.d.ts +2 -0
- package/bin/retailOrg/dtos/Store.js +6 -0
- package/package.json +1 -1
- package/src/platformRbac/dtos/CreateTenantUserRequest.ts +11 -5
- package/src/platformRbac/validators/SuppressInvitationRequiredWithoutRole.ts +14 -0
- package/src/retailIntegration/constants/retailIntegrationLimits.ts +19 -0
- package/src/retailIntegration/dtos/ApplyRetailEventRequest.ts +20 -0
- package/src/retailIntegration/dtos/InventoryEventPayload.ts +33 -0
- package/src/retailIntegration/dtos/ProductEventPayload.ts +51 -0
- package/src/retailIntegration/dtos/RetailUserEventPayload.ts +17 -0
- package/src/retailIntegration/dtos/StoreEventPayload.ts +47 -0
- package/src/retailIntegration/enums/RetailEventRejectCodeEnum.ts +16 -0
- package/src/retailIntegration/enums/RetailMovementTypeEnum.ts +10 -0
- package/src/retailIntegration/enums/index.ts +2 -0
- package/src/retailIntegration/index.ts +5 -0
- package/src/retailIntegration/validators/payloadValidators.ts +56 -0
- package/src/retailOrg/dtos/Store.ts +7 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ProductEventPayload = exports.ProductEventPricePayload = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const retailIntegrationLimits_1 = require("../constants/retailIntegrationLimits");
|
|
16
|
+
const enums_1 = require("../enums");
|
|
17
|
+
const IsIsoDateTimeWithZone_1 = require("../validators/IsIsoDateTimeWithZone");
|
|
18
|
+
const payloadValidators_1 = require("../validators/payloadValidators");
|
|
19
|
+
/** Precio del producto en decimales string. */
|
|
20
|
+
class ProductEventPricePayload {
|
|
21
|
+
}
|
|
22
|
+
exports.ProductEventPricePayload = ProductEventPricePayload;
|
|
23
|
+
__decorate([
|
|
24
|
+
(0, class_validator_1.IsString)(),
|
|
25
|
+
(0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_DECIMAL_PATTERN),
|
|
26
|
+
__metadata("design:type", String)
|
|
27
|
+
], ProductEventPricePayload.prototype, "basePrice", void 0);
|
|
28
|
+
__decorate([
|
|
29
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
30
|
+
(0, class_validator_1.IsString)(),
|
|
31
|
+
(0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_DECIMAL_PATTERN),
|
|
32
|
+
__metadata("design:type", String)
|
|
33
|
+
], ProductEventPricePayload.prototype, "listPrice", void 0);
|
|
34
|
+
__decorate([
|
|
35
|
+
(0, class_validator_1.Validate)(IsIsoDateTimeWithZone_1.IsIsoDateTimeWithZone),
|
|
36
|
+
__metadata("design:type", String)
|
|
37
|
+
], ProductEventPricePayload.prototype, "effectiveFrom", void 0);
|
|
38
|
+
/** Payload de los eventos de producto: el producto completo. */
|
|
39
|
+
class ProductEventPayload {
|
|
40
|
+
}
|
|
41
|
+
exports.ProductEventPayload = ProductEventPayload;
|
|
42
|
+
__decorate([
|
|
43
|
+
(0, class_validator_1.IsString)(),
|
|
44
|
+
(0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_SKU_PATTERN),
|
|
45
|
+
__metadata("design:type", String)
|
|
46
|
+
], ProductEventPayload.prototype, "sku", void 0);
|
|
47
|
+
__decorate([
|
|
48
|
+
(0, class_validator_1.IsString)(),
|
|
49
|
+
(0, class_validator_1.Matches)(/\S/),
|
|
50
|
+
__metadata("design:type", String)
|
|
51
|
+
], ProductEventPayload.prototype, "externalId", void 0);
|
|
52
|
+
__decorate([
|
|
53
|
+
(0, class_validator_1.IsString)(),
|
|
54
|
+
(0, class_validator_1.Matches)(/\S/),
|
|
55
|
+
__metadata("design:type", String)
|
|
56
|
+
], ProductEventPayload.prototype, "brand", void 0);
|
|
57
|
+
__decorate([
|
|
58
|
+
(0, class_validator_1.IsString)(),
|
|
59
|
+
(0, class_validator_1.Matches)(/\S/),
|
|
60
|
+
__metadata("design:type", String)
|
|
61
|
+
], ProductEventPayload.prototype, "model", void 0);
|
|
62
|
+
__decorate([
|
|
63
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
64
|
+
(0, class_validator_1.IsString)(),
|
|
65
|
+
__metadata("design:type", String)
|
|
66
|
+
], ProductEventPayload.prototype, "color", void 0);
|
|
67
|
+
__decorate([
|
|
68
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
69
|
+
(0, class_validator_1.IsString)(),
|
|
70
|
+
__metadata("design:type", String)
|
|
71
|
+
], ProductEventPayload.prototype, "capacity", void 0);
|
|
72
|
+
__decorate([
|
|
73
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
74
|
+
(0, class_validator_1.IsString)(),
|
|
75
|
+
__metadata("design:type", String)
|
|
76
|
+
], ProductEventPayload.prototype, "description", void 0);
|
|
77
|
+
__decorate([
|
|
78
|
+
(0, class_validator_1.IsIn)(Object.values(enums_1.RetailProductCategoryEnum)),
|
|
79
|
+
__metadata("design:type", String)
|
|
80
|
+
], ProductEventPayload.prototype, "category", void 0);
|
|
81
|
+
__decorate([
|
|
82
|
+
(0, class_validator_1.IsIn)(Object.values(enums_1.RetailTrackingModeEnum)),
|
|
83
|
+
__metadata("design:type", String)
|
|
84
|
+
], ProductEventPayload.prototype, "trackingMode", void 0);
|
|
85
|
+
__decorate([
|
|
86
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
87
|
+
(0, class_validator_1.IsIn)(Object.values(enums_1.RetailProductTierEnum)),
|
|
88
|
+
__metadata("design:type", String)
|
|
89
|
+
], ProductEventPayload.prototype, "tier", void 0);
|
|
90
|
+
__decorate([
|
|
91
|
+
(0, class_validator_1.IsIn)(Object.values(enums_1.RetailCurrencyEnum)),
|
|
92
|
+
__metadata("design:type", String)
|
|
93
|
+
], ProductEventPayload.prototype, "currencyId", void 0);
|
|
94
|
+
__decorate([
|
|
95
|
+
(0, class_validator_1.IsDefined)(),
|
|
96
|
+
(0, class_validator_1.ValidateNested)(),
|
|
97
|
+
(0, class_transformer_1.Type)(() => ProductEventPricePayload),
|
|
98
|
+
__metadata("design:type", ProductEventPricePayload)
|
|
99
|
+
], ProductEventPayload.prototype, "price", void 0);
|
|
100
|
+
__decorate([
|
|
101
|
+
(0, class_validator_1.IsArray)(),
|
|
102
|
+
(0, class_validator_1.IsIn)(Object.values(enums_1.RetailFinancierEnum), { each: true }),
|
|
103
|
+
__metadata("design:type", Array)
|
|
104
|
+
], ProductEventPayload.prototype, "eligibleFinanciers", void 0);
|
|
105
|
+
__decorate([
|
|
106
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
107
|
+
(0, class_validator_1.IsIn)(Object.values(enums_1.RetailMdmProviderEnum)),
|
|
108
|
+
__metadata("design:type", String)
|
|
109
|
+
], ProductEventPayload.prototype, "mdmProvider", void 0);
|
|
110
|
+
__decorate([
|
|
111
|
+
(0, class_validator_1.IsIn)(Object.values(enums_1.RetailProductStatusEnum)),
|
|
112
|
+
__metadata("design:type", String)
|
|
113
|
+
], ProductEventPayload.prototype, "status", void 0);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RetailSystemUser, RetailUserAccessStatus, RetailUserRole } from '../models/RetailSystemUser';
|
|
2
|
+
/** Payload de los cuatro eventos de usuario: el usuario completo. */
|
|
3
|
+
export declare class RetailUserEventPayload implements RetailSystemUser {
|
|
4
|
+
retailUserId: string;
|
|
5
|
+
displayName: string;
|
|
6
|
+
email: string;
|
|
7
|
+
phone: string | null;
|
|
8
|
+
homeStoreId: string;
|
|
9
|
+
zoneId: string | null;
|
|
10
|
+
role: RetailUserRole;
|
|
11
|
+
status: RetailUserAccessStatus;
|
|
12
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.RetailUserEventPayload = void 0;
|
|
13
|
+
const class_validator_1 = require("class-validator");
|
|
14
|
+
const retailIntegrationLimits_1 = require("../constants/retailIntegrationLimits");
|
|
15
|
+
const enums_1 = require("../enums");
|
|
16
|
+
const payloadValidators_1 = require("../validators/payloadValidators");
|
|
17
|
+
/** Payload de los cuatro eventos de usuario: el usuario completo. */
|
|
18
|
+
class RetailUserEventPayload {
|
|
19
|
+
}
|
|
20
|
+
exports.RetailUserEventPayload = RetailUserEventPayload;
|
|
21
|
+
__decorate([
|
|
22
|
+
(0, class_validator_1.IsString)(),
|
|
23
|
+
(0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_ENTITY_ID_PATTERN),
|
|
24
|
+
__metadata("design:type", String)
|
|
25
|
+
], RetailUserEventPayload.prototype, "retailUserId", void 0);
|
|
26
|
+
__decorate([
|
|
27
|
+
(0, class_validator_1.IsString)(),
|
|
28
|
+
(0, class_validator_1.Matches)(/\S/),
|
|
29
|
+
__metadata("design:type", String)
|
|
30
|
+
], RetailUserEventPayload.prototype, "displayName", void 0);
|
|
31
|
+
__decorate([
|
|
32
|
+
(0, class_validator_1.IsEmail)(),
|
|
33
|
+
__metadata("design:type", String)
|
|
34
|
+
], RetailUserEventPayload.prototype, "email", void 0);
|
|
35
|
+
__decorate([
|
|
36
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
37
|
+
(0, class_validator_1.IsString)(),
|
|
38
|
+
__metadata("design:type", String)
|
|
39
|
+
], RetailUserEventPayload.prototype, "phone", void 0);
|
|
40
|
+
__decorate([
|
|
41
|
+
(0, class_validator_1.IsString)(),
|
|
42
|
+
(0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_ENTITY_ID_PATTERN),
|
|
43
|
+
__metadata("design:type", String)
|
|
44
|
+
], RetailUserEventPayload.prototype, "homeStoreId", void 0);
|
|
45
|
+
__decorate([
|
|
46
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
47
|
+
(0, class_validator_1.IsString)(),
|
|
48
|
+
(0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_ZONE_ID_PATTERN),
|
|
49
|
+
__metadata("design:type", String)
|
|
50
|
+
], RetailUserEventPayload.prototype, "zoneId", void 0);
|
|
51
|
+
__decorate([
|
|
52
|
+
(0, class_validator_1.IsIn)(Object.values(enums_1.RetailUserRoleEnum)),
|
|
53
|
+
__metadata("design:type", String)
|
|
54
|
+
], RetailUserEventPayload.prototype, "role", void 0);
|
|
55
|
+
__decorate([
|
|
56
|
+
(0, class_validator_1.IsIn)(Object.values(enums_1.RetailUserAccessStatusEnum)),
|
|
57
|
+
__metadata("design:type", String)
|
|
58
|
+
], RetailUserEventPayload.prototype, "status", void 0);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { RetailStoreStatus, RetailSystemStore, RetailSystemStoreAddress, RetailSystemStoreLocation } from '../models/RetailSystemStore';
|
|
2
|
+
/** Dirección de la tienda; los opcionales llegan como `null`, nunca se omiten. */
|
|
3
|
+
export declare class StoreEventAddressPayload implements RetailSystemStoreAddress {
|
|
4
|
+
address1: string;
|
|
5
|
+
externalNumber: string | null;
|
|
6
|
+
internalNumber: string | null;
|
|
7
|
+
neighborhood: string | null;
|
|
8
|
+
city: string;
|
|
9
|
+
state: string;
|
|
10
|
+
zipCode: string;
|
|
11
|
+
country: string | null;
|
|
12
|
+
reference: string | null;
|
|
13
|
+
}
|
|
14
|
+
/** Coordenada de la tienda; `null` si no se informa. */
|
|
15
|
+
export declare class StoreEventLocationPayload implements RetailSystemStoreLocation {
|
|
16
|
+
lat: number | null;
|
|
17
|
+
lng: number | null;
|
|
18
|
+
}
|
|
19
|
+
/** Payload de `StoreCreatedV1`, `StoreUpdatedV1` y `StoreStatusChangedV1`: la tienda completa. */
|
|
20
|
+
export declare class StoreEventPayload implements RetailSystemStore {
|
|
21
|
+
storeId: string;
|
|
22
|
+
code: string;
|
|
23
|
+
name: string;
|
|
24
|
+
zoneId: string | null;
|
|
25
|
+
address: StoreEventAddressPayload;
|
|
26
|
+
location: StoreEventLocationPayload;
|
|
27
|
+
phone: string;
|
|
28
|
+
schedule: string | null;
|
|
29
|
+
status: RetailStoreStatus;
|
|
30
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.StoreEventPayload = exports.StoreEventLocationPayload = exports.StoreEventAddressPayload = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const retailIntegrationLimits_1 = require("../constants/retailIntegrationLimits");
|
|
16
|
+
const enums_1 = require("../enums");
|
|
17
|
+
const payloadValidators_1 = require("../validators/payloadValidators");
|
|
18
|
+
const LAT_MAX = 90;
|
|
19
|
+
const LNG_MAX = 180;
|
|
20
|
+
/** Dirección de la tienda; los opcionales llegan como `null`, nunca se omiten. */
|
|
21
|
+
class StoreEventAddressPayload {
|
|
22
|
+
}
|
|
23
|
+
exports.StoreEventAddressPayload = StoreEventAddressPayload;
|
|
24
|
+
__decorate([
|
|
25
|
+
(0, class_validator_1.IsString)(),
|
|
26
|
+
(0, class_validator_1.Matches)(/\S/),
|
|
27
|
+
__metadata("design:type", String)
|
|
28
|
+
], StoreEventAddressPayload.prototype, "address1", void 0);
|
|
29
|
+
__decorate([
|
|
30
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
31
|
+
(0, class_validator_1.IsString)(),
|
|
32
|
+
__metadata("design:type", String)
|
|
33
|
+
], StoreEventAddressPayload.prototype, "externalNumber", void 0);
|
|
34
|
+
__decorate([
|
|
35
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
36
|
+
(0, class_validator_1.IsString)(),
|
|
37
|
+
__metadata("design:type", String)
|
|
38
|
+
], StoreEventAddressPayload.prototype, "internalNumber", void 0);
|
|
39
|
+
__decorate([
|
|
40
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
41
|
+
(0, class_validator_1.IsString)(),
|
|
42
|
+
__metadata("design:type", String)
|
|
43
|
+
], StoreEventAddressPayload.prototype, "neighborhood", void 0);
|
|
44
|
+
__decorate([
|
|
45
|
+
(0, class_validator_1.IsString)(),
|
|
46
|
+
(0, class_validator_1.Matches)(/\S/),
|
|
47
|
+
__metadata("design:type", String)
|
|
48
|
+
], StoreEventAddressPayload.prototype, "city", void 0);
|
|
49
|
+
__decorate([
|
|
50
|
+
(0, class_validator_1.IsString)(),
|
|
51
|
+
(0, class_validator_1.Matches)(/\S/),
|
|
52
|
+
__metadata("design:type", String)
|
|
53
|
+
], StoreEventAddressPayload.prototype, "state", void 0);
|
|
54
|
+
__decorate([
|
|
55
|
+
(0, class_validator_1.IsString)(),
|
|
56
|
+
(0, class_validator_1.Length)(retailIntegrationLimits_1.RETAIL_ZIP_CODE_MIN_LENGTH, retailIntegrationLimits_1.RETAIL_ZIP_CODE_MAX_LENGTH),
|
|
57
|
+
__metadata("design:type", String)
|
|
58
|
+
], StoreEventAddressPayload.prototype, "zipCode", void 0);
|
|
59
|
+
__decorate([
|
|
60
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
61
|
+
(0, class_validator_1.IsString)(),
|
|
62
|
+
__metadata("design:type", String)
|
|
63
|
+
], StoreEventAddressPayload.prototype, "country", void 0);
|
|
64
|
+
__decorate([
|
|
65
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
66
|
+
(0, class_validator_1.IsString)(),
|
|
67
|
+
__metadata("design:type", String)
|
|
68
|
+
], StoreEventAddressPayload.prototype, "reference", void 0);
|
|
69
|
+
/** Coordenada de la tienda; `null` si no se informa. */
|
|
70
|
+
class StoreEventLocationPayload {
|
|
71
|
+
}
|
|
72
|
+
exports.StoreEventLocationPayload = StoreEventLocationPayload;
|
|
73
|
+
__decorate([
|
|
74
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
75
|
+
(0, class_validator_1.IsNumber)(),
|
|
76
|
+
(0, class_validator_1.Min)(-LAT_MAX),
|
|
77
|
+
(0, class_validator_1.Max)(LAT_MAX),
|
|
78
|
+
__metadata("design:type", Number)
|
|
79
|
+
], StoreEventLocationPayload.prototype, "lat", void 0);
|
|
80
|
+
__decorate([
|
|
81
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
82
|
+
(0, class_validator_1.IsNumber)(),
|
|
83
|
+
(0, class_validator_1.Min)(-LNG_MAX),
|
|
84
|
+
(0, class_validator_1.Max)(LNG_MAX),
|
|
85
|
+
__metadata("design:type", Number)
|
|
86
|
+
], StoreEventLocationPayload.prototype, "lng", void 0);
|
|
87
|
+
/** Payload de `StoreCreatedV1`, `StoreUpdatedV1` y `StoreStatusChangedV1`: la tienda completa. */
|
|
88
|
+
class StoreEventPayload {
|
|
89
|
+
}
|
|
90
|
+
exports.StoreEventPayload = StoreEventPayload;
|
|
91
|
+
__decorate([
|
|
92
|
+
(0, class_validator_1.IsString)(),
|
|
93
|
+
(0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_ENTITY_ID_PATTERN),
|
|
94
|
+
__metadata("design:type", String)
|
|
95
|
+
], StoreEventPayload.prototype, "storeId", void 0);
|
|
96
|
+
__decorate([
|
|
97
|
+
(0, class_validator_1.IsString)(),
|
|
98
|
+
(0, class_validator_1.Length)(1, retailIntegrationLimits_1.RETAIL_STORE_CODE_MAX_LENGTH),
|
|
99
|
+
__metadata("design:type", String)
|
|
100
|
+
], StoreEventPayload.prototype, "code", void 0);
|
|
101
|
+
__decorate([
|
|
102
|
+
(0, class_validator_1.IsString)(),
|
|
103
|
+
(0, class_validator_1.Matches)(/\S/),
|
|
104
|
+
__metadata("design:type", String)
|
|
105
|
+
], StoreEventPayload.prototype, "name", void 0);
|
|
106
|
+
__decorate([
|
|
107
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
108
|
+
(0, class_validator_1.IsString)(),
|
|
109
|
+
(0, class_validator_1.Matches)(retailIntegrationLimits_1.RETAIL_ZONE_ID_PATTERN),
|
|
110
|
+
__metadata("design:type", String)
|
|
111
|
+
], StoreEventPayload.prototype, "zoneId", void 0);
|
|
112
|
+
__decorate([
|
|
113
|
+
(0, class_validator_1.IsDefined)(),
|
|
114
|
+
(0, class_validator_1.ValidateNested)(),
|
|
115
|
+
(0, class_transformer_1.Type)(() => StoreEventAddressPayload),
|
|
116
|
+
__metadata("design:type", StoreEventAddressPayload)
|
|
117
|
+
], StoreEventPayload.prototype, "address", void 0);
|
|
118
|
+
__decorate([
|
|
119
|
+
(0, class_validator_1.IsDefined)(),
|
|
120
|
+
(0, class_validator_1.ValidateNested)(),
|
|
121
|
+
(0, class_transformer_1.Type)(() => StoreEventLocationPayload),
|
|
122
|
+
__metadata("design:type", StoreEventLocationPayload)
|
|
123
|
+
], StoreEventPayload.prototype, "location", void 0);
|
|
124
|
+
__decorate([
|
|
125
|
+
(0, class_validator_1.IsString)(),
|
|
126
|
+
(0, class_validator_1.Matches)(/\S/),
|
|
127
|
+
__metadata("design:type", String)
|
|
128
|
+
], StoreEventPayload.prototype, "phone", void 0);
|
|
129
|
+
__decorate([
|
|
130
|
+
(0, class_validator_1.ValidateIf)(payloadValidators_1.isNullOrValidated),
|
|
131
|
+
(0, class_validator_1.IsString)(),
|
|
132
|
+
__metadata("design:type", String)
|
|
133
|
+
], StoreEventPayload.prototype, "schedule", void 0);
|
|
134
|
+
__decorate([
|
|
135
|
+
(0, class_validator_1.IsIn)(Object.values(enums_1.RetailStoreStatusEnum)),
|
|
136
|
+
__metadata("design:type", String)
|
|
137
|
+
], StoreEventPayload.prototype, "status", void 0);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** `code` de un `REJECTED`; uno solo para los cuatro endpoints que aplican eventos del retailer. */
|
|
2
|
+
export declare enum RetailEventRejectCodeEnum {
|
|
3
|
+
INVALID_PAYLOAD = "INVALID_PAYLOAD",
|
|
4
|
+
STORE_RETAILER_MISMATCH = "STORE_RETAILER_MISMATCH",
|
|
5
|
+
RETAIL_USER_RETAILER_MISMATCH = "RETAIL_USER_RETAILER_MISMATCH",
|
|
6
|
+
STORE_CODE_TAKEN = "STORE_CODE_TAKEN",
|
|
7
|
+
EMAIL_ALREADY_IN_USE = "EMAIL_ALREADY_IN_USE",
|
|
8
|
+
UNSUPPORTED_CURRENCY = "UNSUPPORTED_CURRENCY",
|
|
9
|
+
FUTURE_PRICE_NOT_SUPPORTED = "FUTURE_PRICE_NOT_SUPPORTED",
|
|
10
|
+
SKU_OWNED_BY_BACKOFFICE = "SKU_OWNED_BY_BACKOFFICE",
|
|
11
|
+
STORE_NOT_IN_RETAILER = "STORE_NOT_IN_RETAILER",
|
|
12
|
+
SKU_NOT_STOCKABLE = "SKU_NOT_STOCKABLE",
|
|
13
|
+
TRACKING_MODE_MISMATCH = "TRACKING_MODE_MISMATCH",
|
|
14
|
+
INVALID_IMEI = "INVALID_IMEI",
|
|
15
|
+
IDENTIFIER_CONFLICT = "IDENTIFIER_CONFLICT"
|
|
16
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RetailEventRejectCodeEnum = void 0;
|
|
4
|
+
/** `code` de un `REJECTED`; uno solo para los cuatro endpoints que aplican eventos del retailer. */
|
|
5
|
+
var RetailEventRejectCodeEnum;
|
|
6
|
+
(function (RetailEventRejectCodeEnum) {
|
|
7
|
+
RetailEventRejectCodeEnum["INVALID_PAYLOAD"] = "INVALID_PAYLOAD";
|
|
8
|
+
RetailEventRejectCodeEnum["STORE_RETAILER_MISMATCH"] = "STORE_RETAILER_MISMATCH";
|
|
9
|
+
RetailEventRejectCodeEnum["RETAIL_USER_RETAILER_MISMATCH"] = "RETAIL_USER_RETAILER_MISMATCH";
|
|
10
|
+
RetailEventRejectCodeEnum["STORE_CODE_TAKEN"] = "STORE_CODE_TAKEN";
|
|
11
|
+
RetailEventRejectCodeEnum["EMAIL_ALREADY_IN_USE"] = "EMAIL_ALREADY_IN_USE";
|
|
12
|
+
RetailEventRejectCodeEnum["UNSUPPORTED_CURRENCY"] = "UNSUPPORTED_CURRENCY";
|
|
13
|
+
RetailEventRejectCodeEnum["FUTURE_PRICE_NOT_SUPPORTED"] = "FUTURE_PRICE_NOT_SUPPORTED";
|
|
14
|
+
RetailEventRejectCodeEnum["SKU_OWNED_BY_BACKOFFICE"] = "SKU_OWNED_BY_BACKOFFICE";
|
|
15
|
+
RetailEventRejectCodeEnum["STORE_NOT_IN_RETAILER"] = "STORE_NOT_IN_RETAILER";
|
|
16
|
+
RetailEventRejectCodeEnum["SKU_NOT_STOCKABLE"] = "SKU_NOT_STOCKABLE";
|
|
17
|
+
RetailEventRejectCodeEnum["TRACKING_MODE_MISMATCH"] = "TRACKING_MODE_MISMATCH";
|
|
18
|
+
RetailEventRejectCodeEnum["INVALID_IMEI"] = "INVALID_IMEI";
|
|
19
|
+
RetailEventRejectCodeEnum["IDENTIFIER_CONFLICT"] = "IDENTIFIER_CONFLICT";
|
|
20
|
+
})(RetailEventRejectCodeEnum || (exports.RetailEventRejectCodeEnum = RetailEventRejectCodeEnum = {}));
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** `payload.movementType` de `InventoryMovementV1`. */
|
|
2
|
+
export declare enum RetailMovementTypeEnum {
|
|
3
|
+
ENTRY = "ENTRY",
|
|
4
|
+
SALE = "SALE",
|
|
5
|
+
RETURN = "RETURN",
|
|
6
|
+
ADJUSTMENT = "ADJUSTMENT",
|
|
7
|
+
TRANSFER_OUT = "TRANSFER_OUT",
|
|
8
|
+
TRANSFER_IN = "TRANSFER_IN",
|
|
9
|
+
TRANSFER_CANCEL = "TRANSFER_CANCEL"
|
|
10
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RetailMovementTypeEnum = void 0;
|
|
4
|
+
/** `payload.movementType` de `InventoryMovementV1`. */
|
|
5
|
+
var RetailMovementTypeEnum;
|
|
6
|
+
(function (RetailMovementTypeEnum) {
|
|
7
|
+
RetailMovementTypeEnum["ENTRY"] = "ENTRY";
|
|
8
|
+
RetailMovementTypeEnum["SALE"] = "SALE";
|
|
9
|
+
RetailMovementTypeEnum["RETURN"] = "RETURN";
|
|
10
|
+
RetailMovementTypeEnum["ADJUSTMENT"] = "ADJUSTMENT";
|
|
11
|
+
RetailMovementTypeEnum["TRANSFER_OUT"] = "TRANSFER_OUT";
|
|
12
|
+
RetailMovementTypeEnum["TRANSFER_IN"] = "TRANSFER_IN";
|
|
13
|
+
RetailMovementTypeEnum["TRANSFER_CANCEL"] = "TRANSFER_CANCEL";
|
|
14
|
+
})(RetailMovementTypeEnum || (exports.RetailMovementTypeEnum = RetailMovementTypeEnum = {}));
|
|
@@ -19,3 +19,5 @@ export * from './RetailSaleTypeEnum';
|
|
|
19
19
|
export * from './RetailSaleFinancierEnum';
|
|
20
20
|
export * from './RetailPaymentMethodEnum';
|
|
21
21
|
export * from './RetailLinePaymentTypeEnum';
|
|
22
|
+
export * from './RetailEventRejectCodeEnum';
|
|
23
|
+
export * from './RetailMovementTypeEnum';
|
|
@@ -35,3 +35,5 @@ __exportStar(require("./RetailSaleTypeEnum"), exports);
|
|
|
35
35
|
__exportStar(require("./RetailSaleFinancierEnum"), exports);
|
|
36
36
|
__exportStar(require("./RetailPaymentMethodEnum"), exports);
|
|
37
37
|
__exportStar(require("./RetailLinePaymentTypeEnum"), exports);
|
|
38
|
+
__exportStar(require("./RetailEventRejectCodeEnum"), exports);
|
|
39
|
+
__exportStar(require("./RetailMovementTypeEnum"), exports);
|
|
@@ -9,6 +9,11 @@ export * from './dtos/ReceiveInventoryEventRequest';
|
|
|
9
9
|
export * from './dtos/ReceiveRetailEventRequest';
|
|
10
10
|
export * from './dtos/RetailEventResult';
|
|
11
11
|
export * from './dtos/ApplyRetailEventRequest';
|
|
12
|
+
export * from './validators/payloadValidators';
|
|
13
|
+
export * from './dtos/StoreEventPayload';
|
|
14
|
+
export * from './dtos/RetailUserEventPayload';
|
|
15
|
+
export * from './dtos/ProductEventPayload';
|
|
16
|
+
export * from './dtos/InventoryEventPayload';
|
|
12
17
|
export * from './dtos/RetailTenantQuery';
|
|
13
18
|
export * from './dtos/RetailPagedQuery';
|
|
14
19
|
export * from './dtos/ListRetailStoresRequest';
|
|
@@ -25,6 +25,11 @@ __exportStar(require("./dtos/ReceiveInventoryEventRequest"), exports);
|
|
|
25
25
|
__exportStar(require("./dtos/ReceiveRetailEventRequest"), exports);
|
|
26
26
|
__exportStar(require("./dtos/RetailEventResult"), exports);
|
|
27
27
|
__exportStar(require("./dtos/ApplyRetailEventRequest"), exports);
|
|
28
|
+
__exportStar(require("./validators/payloadValidators"), exports);
|
|
29
|
+
__exportStar(require("./dtos/StoreEventPayload"), exports);
|
|
30
|
+
__exportStar(require("./dtos/RetailUserEventPayload"), exports);
|
|
31
|
+
__exportStar(require("./dtos/ProductEventPayload"), exports);
|
|
32
|
+
__exportStar(require("./dtos/InventoryEventPayload"), exports);
|
|
28
33
|
__exportStar(require("./dtos/RetailTenantQuery"), exports);
|
|
29
34
|
__exportStar(require("./dtos/RetailPagedQuery"), exports);
|
|
30
35
|
__exportStar(require("./dtos/ListRetailStoresRequest"), exports);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ValidationArguments, ValidatorConstraintInterface } from 'class-validator';
|
|
2
|
+
/** `ValidateIf` de un campo nullable: con `null` no valida; ausente sí, porque el contrato nunca omite llaves. */
|
|
3
|
+
export declare function isNullOrValidated(_object: object, value: unknown): boolean;
|
|
4
|
+
/** Rechaza un arreglo de objetos con dos elementos que repiten la llave compuesta de `constraints`. */
|
|
5
|
+
export declare class HasUniqueKeys implements ValidatorConstraintInterface {
|
|
6
|
+
validate(value: unknown, args: ValidationArguments): boolean;
|
|
7
|
+
defaultMessage(args: ValidationArguments): string;
|
|
8
|
+
}
|
|
9
|
+
/** `targetStoreId`: obligatorio en `TRANSFER_OUT` y `null` en los demás movimientos. */
|
|
10
|
+
export declare class TargetStoreMatchesMovement implements ValidatorConstraintInterface {
|
|
11
|
+
validate(value: unknown, args: ValidationArguments): boolean;
|
|
12
|
+
defaultMessage(): string;
|
|
13
|
+
}
|
|
14
|
+
/** `reason`: obligatorio en `DAMAGED` y `null` en los demás estados. */
|
|
15
|
+
export declare class ReasonMatchesStatus implements ValidatorConstraintInterface {
|
|
16
|
+
validate(value: unknown, args: ValidationArguments): boolean;
|
|
17
|
+
defaultMessage(): string;
|
|
18
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ReasonMatchesStatus = exports.TargetStoreMatchesMovement = exports.HasUniqueKeys = void 0;
|
|
10
|
+
exports.isNullOrValidated = isNullOrValidated;
|
|
11
|
+
const class_validator_1 = require("class-validator");
|
|
12
|
+
const retailIntegrationLimits_1 = require("../constants/retailIntegrationLimits");
|
|
13
|
+
const enums_1 = require("../enums");
|
|
14
|
+
/** `ValidateIf` de un campo nullable: con `null` no valida; ausente sí, porque el contrato nunca omite llaves. */
|
|
15
|
+
function isNullOrValidated(_object, value) {
|
|
16
|
+
return value !== null;
|
|
17
|
+
}
|
|
18
|
+
/** Rechaza un arreglo de objetos con dos elementos que repiten la llave compuesta de `constraints`. */
|
|
19
|
+
let HasUniqueKeys = class HasUniqueKeys {
|
|
20
|
+
validate(value, args) {
|
|
21
|
+
if (!Array.isArray(value))
|
|
22
|
+
return true;
|
|
23
|
+
const keys = args.constraints;
|
|
24
|
+
const seen = new Set();
|
|
25
|
+
for (const item of value) {
|
|
26
|
+
const key = keys.map((k) => String(item?.[k])).join('#');
|
|
27
|
+
if (seen.has(key))
|
|
28
|
+
return false;
|
|
29
|
+
seen.add(key);
|
|
30
|
+
}
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
defaultMessage(args) {
|
|
34
|
+
return `no puede repetir ${args.constraints.join(' + ')}`;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
exports.HasUniqueKeys = HasUniqueKeys;
|
|
38
|
+
exports.HasUniqueKeys = HasUniqueKeys = __decorate([
|
|
39
|
+
(0, class_validator_1.ValidatorConstraint)({ name: 'hasUniqueKeys', async: false })
|
|
40
|
+
], HasUniqueKeys);
|
|
41
|
+
/** `targetStoreId`: obligatorio en `TRANSFER_OUT` y `null` en los demás movimientos. */
|
|
42
|
+
let TargetStoreMatchesMovement = class TargetStoreMatchesMovement {
|
|
43
|
+
validate(value, args) {
|
|
44
|
+
const movementType = args.object.movementType;
|
|
45
|
+
if (movementType === enums_1.RetailMovementTypeEnum.TRANSFER_OUT)
|
|
46
|
+
return typeof value === 'string' && retailIntegrationLimits_1.RETAIL_ENTITY_ID_PATTERN.test(value);
|
|
47
|
+
return value === null;
|
|
48
|
+
}
|
|
49
|
+
defaultMessage() {
|
|
50
|
+
return 'targetStoreId es obligatorio en TRANSFER_OUT y null en los demás movimientos';
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
exports.TargetStoreMatchesMovement = TargetStoreMatchesMovement;
|
|
54
|
+
exports.TargetStoreMatchesMovement = TargetStoreMatchesMovement = __decorate([
|
|
55
|
+
(0, class_validator_1.ValidatorConstraint)({ name: 'targetStoreMatchesMovement', async: false })
|
|
56
|
+
], TargetStoreMatchesMovement);
|
|
57
|
+
/** `reason`: obligatorio en `DAMAGED` y `null` en los demás estados. */
|
|
58
|
+
let ReasonMatchesStatus = class ReasonMatchesStatus {
|
|
59
|
+
validate(value, args) {
|
|
60
|
+
const status = args.object.status;
|
|
61
|
+
if (status === enums_1.RetailPieceStatusEnum.DAMAGED)
|
|
62
|
+
return Object.values(enums_1.RetailPieceReasonEnum).includes(value);
|
|
63
|
+
return value === null;
|
|
64
|
+
}
|
|
65
|
+
defaultMessage() {
|
|
66
|
+
return 'reason es obligatorio con DAMAGED y null en los demás estados';
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
exports.ReasonMatchesStatus = ReasonMatchesStatus;
|
|
70
|
+
exports.ReasonMatchesStatus = ReasonMatchesStatus = __decorate([
|
|
71
|
+
(0, class_validator_1.ValidatorConstraint)({ name: 'reasonMatchesStatus', async: false })
|
|
72
|
+
], ReasonMatchesStatus);
|
|
@@ -29,6 +29,8 @@ export declare class Store {
|
|
|
29
29
|
*/
|
|
30
30
|
dailyAvgCollectionsCount: number | null;
|
|
31
31
|
status: StoreStatusEnum;
|
|
32
|
+
/** `true` si la tienda la administra la integración del retailer y no se edita a mano. */
|
|
33
|
+
managedByIntegration?: boolean;
|
|
32
34
|
createdAt: string;
|
|
33
35
|
updatedAt: string;
|
|
34
36
|
createdBy: string;
|
|
@@ -93,6 +93,12 @@ __decorate([
|
|
|
93
93
|
(0, class_validator_1.IsEnum)(StoreStatusEnum_1.StoreStatusEnum),
|
|
94
94
|
__metadata("design:type", String)
|
|
95
95
|
], Store.prototype, "status", void 0);
|
|
96
|
+
__decorate([
|
|
97
|
+
(0, class_transformer_1.Expose)(),
|
|
98
|
+
(0, class_validator_1.IsOptional)(),
|
|
99
|
+
(0, class_validator_1.IsBoolean)(),
|
|
100
|
+
__metadata("design:type", Boolean)
|
|
101
|
+
], Store.prototype, "managedByIntegration", void 0);
|
|
96
102
|
__decorate([
|
|
97
103
|
(0, class_transformer_1.Expose)(),
|
|
98
104
|
(0, class_validator_1.IsString)(),
|
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { Expose } from 'class-transformer';
|
|
2
|
-
import { IsEmail, IsEnum, IsNotEmpty, IsObject, IsOptional, IsString, Validate } from 'class-validator';
|
|
2
|
+
import { IsEmail, IsEnum, IsNotEmpty, IsObject, IsOptional, IsString, Validate, ValidateIf } from 'class-validator';
|
|
3
3
|
import { PermissionScope } from '../enums/PermissionScope';
|
|
4
4
|
import { IsStringValueRecord } from '../../common/validators/IsStringValueRecord';
|
|
5
|
+
import { SuppressInvitationRequiredWithoutRole } from '../validators/SuppressInvitationRequiredWithoutRole';
|
|
6
|
+
|
|
7
|
+
const hasAnyGrantField = (o: CreateTenantUserRequest): boolean =>
|
|
8
|
+
o.roleId !== undefined || o.scope !== undefined || o.scopeRef !== undefined;
|
|
5
9
|
|
|
6
10
|
/**
|
|
7
11
|
* Body del POST /internal/tenants/{tenantId}/users (endpoint privado, VPC/ANONIMUS). `tenantId` viaja en el path.
|
|
@@ -10,16 +14,18 @@ import { IsStringValueRecord } from '../../common/validators/IsStringValueRecord
|
|
|
10
14
|
* Consumido por el alta de usuario orquestada de SureKeep F1 (retail-org → RBAC → RetailUser) vía api-invoker.
|
|
11
15
|
* - Usuario provisionado en estado INVITED (mitiga orphan si el paso siguiente en retail-org falla).
|
|
12
16
|
* - Idempotente por identidad Cognito.
|
|
13
|
-
* - `scope`/`scopeRef
|
|
17
|
+
* - `roleId`/`scope`/`scopeRef`: todos o ninguno; sin rol no hay invitación.
|
|
14
18
|
* - `createdBy` = cognitoSub del admin real (audit + grantedBy del assignment).
|
|
15
19
|
* - `customFields` = valores de los campos personalizados del tenant; si el correo ya tiene usuario, se fusionan.
|
|
16
20
|
*/
|
|
17
21
|
export class CreateTenantUserRequest {
|
|
18
22
|
@Expose() @IsEmail() email!: string;
|
|
19
23
|
@Expose() @IsOptional() @IsString() @IsNotEmpty() displayName?: string;
|
|
20
|
-
@Expose() @IsString() @IsNotEmpty() roleId
|
|
21
|
-
@Expose() @IsEnum(PermissionScope) scope
|
|
22
|
-
@Expose() @IsString() @IsNotEmpty() scopeRef
|
|
24
|
+
@Expose() @ValidateIf(hasAnyGrantField) @IsString() @IsNotEmpty() roleId?: string;
|
|
25
|
+
@Expose() @ValidateIf(hasAnyGrantField) @IsEnum(PermissionScope) scope?: PermissionScope;
|
|
26
|
+
@Expose() @ValidateIf(hasAnyGrantField) @IsString() @IsNotEmpty() scopeRef?: string;
|
|
27
|
+
/** Solo en el alta sin rol: no se manda invitación hasta que alguien asigne el primer rol. */
|
|
28
|
+
@Expose() @Validate(SuppressInvitationRequiredWithoutRole) suppressInvitation?: boolean;
|
|
23
29
|
@Expose() @IsString() @IsNotEmpty() createdBy!: string;
|
|
24
30
|
@Expose()
|
|
25
31
|
@IsOptional()
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ValidationArguments, ValidatorConstraint, ValidatorConstraintInterface } from 'class-validator';
|
|
2
|
+
|
|
3
|
+
/** Sin rol el alta exige `suppressInvitation: true`; con rol no se admite, porque el alta con rol siempre invita. */
|
|
4
|
+
@ValidatorConstraint({ name: 'suppressInvitationRequiredWithoutRole', async: false })
|
|
5
|
+
export class SuppressInvitationRequiredWithoutRole implements ValidatorConstraintInterface {
|
|
6
|
+
validate(value: unknown, args: ValidationArguments): boolean {
|
|
7
|
+
const hasRole = (args.object as { roleId?: unknown }).roleId !== undefined;
|
|
8
|
+
return hasRole ? value === undefined : value === true;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
defaultMessage(): string {
|
|
12
|
+
return 'suppressInvitation: true va solo y siempre en el alta sin rol';
|
|
13
|
+
}
|
|
14
|
+
}
|