@fiado/type-kit 3.260.0 → 3.262.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/PasswordPolicyInput.test.ts +58 -0
- package/_test_/unit/retailWizard/saleFinancier.test.ts +68 -0
- package/bin/benefitCenter/enums/BenefitFlowEnum.d.ts +11 -0
- package/bin/benefitCenter/enums/BenefitFlowEnum.js +15 -0
- package/bin/identity/dtos/PeopleResponse.d.ts +9 -0
- package/bin/identity/enums/SelfieSourceEnum.d.ts +10 -0
- package/bin/identity/enums/SelfieSourceEnum.js +14 -0
- package/bin/platformRbac/application/Application.d.ts +17 -0
- package/bin/platformRbac/dtos/CreateTenantRequest.d.ts +12 -0
- package/bin/platformRbac/dtos/CreateTenantRequest.js +8 -0
- package/bin/platformRbac/dtos/PasswordPolicyInput.d.ts +30 -0
- package/bin/platformRbac/dtos/PasswordPolicyInput.js +72 -0
- package/bin/platformRbac/index.d.ts +1 -0
- package/bin/platformRbac/index.js +3 -0
- package/bin/retailWizard/dtos/SaleException.d.ts +54 -0
- package/bin/retailWizard/dtos/SaleException.js +2 -0
- package/bin/retailWizard/dtos/SaleExceptionEvent.d.ts +18 -0
- package/bin/retailWizard/dtos/SaleExceptionEvent.js +2 -0
- package/bin/retailWizard/dtos/SaleExceptionPayload.d.ts +19 -0
- package/bin/retailWizard/dtos/SaleExceptionPayload.js +2 -0
- package/bin/retailWizard/dtos/SaleLogEntry.d.ts +29 -0
- package/bin/retailWizard/dtos/SaleLogEntry.js +2 -0
- package/bin/retailWizard/dtos/SalesReportDefinition.d.ts +20 -0
- package/bin/retailWizard/dtos/SalesReportDefinition.js +2 -0
- package/bin/retailWizard/dtos/SalesReportRun.d.ts +39 -0
- package/bin/retailWizard/dtos/SalesReportRun.js +2 -0
- package/bin/retailWizard/dtos/requests/BackofficeCancelSaleRequest.d.ts +26 -0
- package/bin/retailWizard/dtos/requests/BackofficeCancelSaleRequest.js +48 -0
- package/bin/retailWizard/dtos/requests/CreateSaleExceptionRequest.d.ts +28 -0
- package/bin/retailWizard/dtos/requests/CreateSaleExceptionRequest.js +96 -0
- package/bin/retailWizard/dtos/requests/ResolveSaleExceptionRequest.d.ts +15 -0
- package/bin/retailWizard/dtos/requests/ResolveSaleExceptionRequest.js +40 -0
- package/bin/retailWizard/dtos/requests/RunSalesReportRequest.d.ts +18 -0
- package/bin/retailWizard/dtos/requests/RunSalesReportRequest.js +45 -0
- package/bin/retailWizard/dtos/responses/BackofficeReportsResponse.d.ts +14 -0
- package/bin/retailWizard/dtos/responses/BackofficeReportsResponse.js +2 -0
- package/bin/retailWizard/dtos/responses/BackofficeSalesKpisResponse.d.ts +32 -0
- package/bin/retailWizard/dtos/responses/BackofficeSalesKpisResponse.js +2 -0
- package/bin/retailWizard/dtos/responses/BackofficeSalesStatsResponse.d.ts +26 -0
- package/bin/retailWizard/dtos/responses/BackofficeSalesStatsResponse.js +2 -0
- package/bin/retailWizard/enums/ReportFormatEnum.d.ts +5 -0
- package/bin/retailWizard/enums/ReportFormatEnum.js +9 -0
- package/bin/retailWizard/enums/ReportPeriodicityEnum.d.ts +9 -0
- package/bin/retailWizard/enums/ReportPeriodicityEnum.js +13 -0
- package/bin/retailWizard/enums/ReportRunStatusEnum.d.ts +18 -0
- package/bin/retailWizard/enums/ReportRunStatusEnum.js +22 -0
- package/bin/retailWizard/enums/SaleExceptionDecisionEnum.d.ts +10 -0
- package/bin/retailWizard/enums/SaleExceptionDecisionEnum.js +14 -0
- package/bin/retailWizard/enums/SaleExceptionEventKindEnum.d.ts +17 -0
- package/bin/retailWizard/enums/SaleExceptionEventKindEnum.js +21 -0
- package/bin/retailWizard/enums/SaleExceptionStatusEnum.d.ts +19 -0
- package/bin/retailWizard/enums/SaleExceptionStatusEnum.js +23 -0
- package/bin/retailWizard/enums/SaleExceptionTypeEnum.d.ts +19 -0
- package/bin/retailWizard/enums/SaleExceptionTypeEnum.js +23 -0
- package/bin/retailWizard/enums/SaleFinancierEnum.d.ts +18 -0
- package/bin/retailWizard/enums/SaleFinancierEnum.js +22 -0
- package/bin/retailWizard/enums/SalesReportIdEnum.d.ts +19 -0
- package/bin/retailWizard/enums/SalesReportIdEnum.js +23 -0
- package/bin/retailWizard/helpers/saleFinancier.d.ts +21 -0
- package/bin/retailWizard/helpers/saleFinancier.js +44 -0
- package/bin/retailWizard/index.d.ts +23 -0
- package/bin/retailWizard/index.js +29 -0
- package/bin/walletFunding/dtos/CancelFundingReferenceRequest.d.ts +6 -0
- package/bin/walletFunding/dtos/CancelFundingReferenceRequest.js +31 -0
- package/bin/walletFunding/dtos/CancelFundingReferenceResponse.d.ts +7 -0
- package/bin/walletFunding/dtos/CancelFundingReferenceResponse.js +6 -0
- package/bin/walletFunding/dtos/CancelFundingRequest.d.ts +11 -0
- package/bin/walletFunding/dtos/CancelFundingRequest.js +33 -0
- package/bin/walletFunding/dtos/CancelFundingResponse.d.ts +14 -0
- package/bin/walletFunding/dtos/CancelFundingResponse.js +12 -0
- package/bin/walletFunding/dtos/CancelWalletFundingRequest.d.ts +3 -0
- package/bin/walletFunding/dtos/CancelWalletFundingRequest.js +21 -0
- package/bin/walletFunding/dtos/CancelWalletFundingResponse.d.ts +7 -0
- package/bin/walletFunding/dtos/CancelWalletFundingResponse.js +6 -0
- package/package.json +1 -1
- package/src/identity/dtos/PeopleResponse.ts +9 -0
- package/src/platformRbac/application/Application.ts +17 -0
- package/src/platformRbac/dtos/CreateTenantRequest.ts +13 -0
- package/src/platformRbac/dtos/PasswordPolicyInput.ts +42 -0
- package/src/platformRbac/index.ts +3 -0
- package/src/retailWizard/dtos/SaleException.ts +55 -0
- package/src/retailWizard/dtos/SaleExceptionEvent.ts +19 -0
- package/src/retailWizard/dtos/SaleExceptionPayload.ts +19 -0
- package/src/retailWizard/dtos/SaleLogEntry.ts +30 -0
- package/src/retailWizard/dtos/SalesReportDefinition.ts +21 -0
- package/src/retailWizard/dtos/SalesReportRun.ts +40 -0
- package/src/retailWizard/dtos/requests/BackofficeCancelSaleRequest.ts +42 -0
- package/src/retailWizard/dtos/requests/CreateSaleExceptionRequest.ts +84 -0
- package/src/retailWizard/dtos/requests/ResolveSaleExceptionRequest.ts +25 -0
- package/src/retailWizard/dtos/requests/RunSalesReportRequest.ts +31 -0
- package/src/retailWizard/dtos/responses/BackofficeReportsResponse.ts +15 -0
- package/src/retailWizard/dtos/responses/BackofficeSalesKpisResponse.ts +34 -0
- package/src/retailWizard/dtos/responses/BackofficeSalesStatsResponse.ts +26 -0
- package/src/retailWizard/enums/ReportFormatEnum.ts +5 -0
- package/src/retailWizard/enums/ReportPeriodicityEnum.ts +9 -0
- package/src/retailWizard/enums/ReportRunStatusEnum.ts +18 -0
- package/src/retailWizard/enums/SaleExceptionDecisionEnum.ts +10 -0
- package/src/retailWizard/enums/SaleExceptionEventKindEnum.ts +17 -0
- package/src/retailWizard/enums/SaleExceptionStatusEnum.ts +19 -0
- package/src/retailWizard/enums/SaleExceptionTypeEnum.ts +19 -0
- package/src/retailWizard/enums/SaleFinancierEnum.ts +18 -0
- package/src/retailWizard/enums/SalesReportIdEnum.ts +19 -0
- package/src/retailWizard/helpers/saleFinancier.ts +48 -0
- package/src/retailWizard/index.ts +34 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { plainToInstance } from 'class-transformer';
|
|
3
|
+
import { validateSync } from 'class-validator';
|
|
4
|
+
|
|
5
|
+
import { PasswordPolicyInput } from '../../../src/platformRbac/dtos/PasswordPolicyInput';
|
|
6
|
+
|
|
7
|
+
// DEC-RBAC-111: política de contraseña per-tenant. Los 5 campos son opcionales — un campo ausente
|
|
8
|
+
// cae a la plantilla de la app y, de ahí, a la policy global del lambda.
|
|
9
|
+
describe('PasswordPolicyInput', () => {
|
|
10
|
+
it('acepta los 5 campos válidos', () => {
|
|
11
|
+
const dto = plainToInstance(PasswordPolicyInput, {
|
|
12
|
+
minLength: 16,
|
|
13
|
+
requireUppercase: true,
|
|
14
|
+
requireLowercase: true,
|
|
15
|
+
requireNumber: true,
|
|
16
|
+
requireSymbol: true,
|
|
17
|
+
});
|
|
18
|
+
expect(validateSync(dto)).toHaveLength(0);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('acepta el objeto vacío (todos los campos son opcionales)', () => {
|
|
22
|
+
expect(validateSync(plainToInstance(PasswordPolicyInput, {}))).toHaveLength(0);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Cognito acepta PasswordPolicy.MinimumLength en 6..99. Fuera de ese rango, CreateUserPool tira
|
|
26
|
+
// InvalidParameterException DESPUÉS de que la saga de onboarding ya escribió la ficha del tenant
|
|
27
|
+
// en estado 'provisioning' — o sea el fallo cae en la rama de compensación. Se ataja acá.
|
|
28
|
+
it.each([5, 100, 150])('rechaza minLength %i (fuera del rango 6-99 de Cognito)', (minLength) => {
|
|
29
|
+
const errors = validateSync(plainToInstance(PasswordPolicyInput, { minLength }));
|
|
30
|
+
expect(errors).toHaveLength(1);
|
|
31
|
+
expect(errors[0].property).toBe('minLength');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it.each([6, 99])('acepta minLength %i (los bordes del rango de Cognito)', (minLength) => {
|
|
35
|
+
expect(validateSync(plainToInstance(PasswordPolicyInput, { minLength }))).toHaveLength(0);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('rechaza minLength no entero', () => {
|
|
39
|
+
const errors = validateSync(plainToInstance(PasswordPolicyInput, { minLength: 12.5 }));
|
|
40
|
+
expect(errors).toHaveLength(1);
|
|
41
|
+
expect(errors[0].property).toBe('minLength');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('rechaza un require* que no es booleano', () => {
|
|
45
|
+
const errors = validateSync(
|
|
46
|
+
plainToInstance(PasswordPolicyInput, { requireSymbol: 'sí' as unknown as boolean }),
|
|
47
|
+
);
|
|
48
|
+
expect(errors).toHaveLength(1);
|
|
49
|
+
expect(errors[0].property).toBe('requireSymbol');
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// El piso (que la policy no sea MÁS DÉBIL que la global del lambda) NO se valida acá a propósito:
|
|
53
|
+
// depende de env vars del lambda, así que ponerlo también en el type-kit sería una segunda fuente
|
|
54
|
+
// de verdad en otro repo, que driftea en cuanto alguien cambia la env var.
|
|
55
|
+
it('NO rechaza una policy débil: el piso lo decide el lambda, no el type-kit', () => {
|
|
56
|
+
expect(validateSync(plainToInstance(PasswordPolicyInput, { minLength: 6 }))).toHaveLength(0);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { SaleTypeEnum } from '../../../src/retailWizard/enums/SaleTypeEnum';
|
|
2
|
+
import { ExternalProviderEnum } from '../../../src/retailWizard/enums/ExternalProviderEnum';
|
|
3
|
+
import { SaleFinancierEnum } from '../../../src/retailWizard/enums/SaleFinancierEnum';
|
|
4
|
+
import {
|
|
5
|
+
financierOfSale,
|
|
6
|
+
isSureKeepFinanced,
|
|
7
|
+
isExternallyFinanced,
|
|
8
|
+
} from '../../../src/retailWizard/helpers/saleFinancier';
|
|
9
|
+
|
|
10
|
+
describe('financierOfSale', () => {
|
|
11
|
+
it('el contado no tiene financiera', () => {
|
|
12
|
+
expect(financierOfSale({ type: SaleTypeEnum.CASH, externalProvider: null })).toBe(
|
|
13
|
+
SaleFinancierEnum.NONE,
|
|
14
|
+
);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('el crédito propio es SUREKEEP', () => {
|
|
18
|
+
expect(financierOfSale({ type: SaleTypeEnum.CREDIT, externalProvider: null })).toBe(
|
|
19
|
+
SaleFinancierEnum.SUREKEEP,
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it.each([
|
|
24
|
+
[ExternalProviderEnum.PAYJOY, SaleFinancierEnum.PAYJOY],
|
|
25
|
+
[ExternalProviderEnum.CREDIYA, SaleFinancierEnum.CREDIYA],
|
|
26
|
+
[ExternalProviderEnum.LESPAGO, SaleFinancierEnum.LESPAGO],
|
|
27
|
+
[ExternalProviderEnum.INNOVA, SaleFinancierEnum.INNOVA],
|
|
28
|
+
])('la derivación a %s mapea a su financiera', (provider, expected) => {
|
|
29
|
+
expect(financierOfSale({ type: SaleTypeEnum.EXTERNAL_REFERRAL, externalProvider: provider })).toBe(
|
|
30
|
+
expected,
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('una derivación sin proveedor cae en NONE, no revienta (ventas viejas sin el campo)', () => {
|
|
35
|
+
expect(financierOfSale({ type: SaleTypeEnum.EXTERNAL_REFERRAL, externalProvider: null })).toBe(
|
|
36
|
+
SaleFinancierEnum.NONE,
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('el crédito propio gana sobre un externalProvider colado en la fila', () => {
|
|
41
|
+
expect(
|
|
42
|
+
financierOfSale({ type: SaleTypeEnum.CREDIT, externalProvider: ExternalProviderEnum.PAYJOY }),
|
|
43
|
+
).toBe(SaleFinancierEnum.SUREKEEP);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe('particiones de los pills del Admin VL', () => {
|
|
48
|
+
it('SUREKEEP y externas son disjuntas', () => {
|
|
49
|
+
const surekeep = { type: SaleTypeEnum.CREDIT, externalProvider: null };
|
|
50
|
+
expect(isSureKeepFinanced(surekeep)).toBe(true);
|
|
51
|
+
expect(isExternallyFinanced(surekeep)).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('una externa cuenta como externa y no como SureKeep', () => {
|
|
55
|
+
const externa = {
|
|
56
|
+
type: SaleTypeEnum.EXTERNAL_REFERRAL,
|
|
57
|
+
externalProvider: ExternalProviderEnum.CREDIYA,
|
|
58
|
+
};
|
|
59
|
+
expect(isExternallyFinanced(externa)).toBe(true);
|
|
60
|
+
expect(isSureKeepFinanced(externa)).toBe(false);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('el contado NO cuenta en ninguna de las dos: no tiene financiera', () => {
|
|
64
|
+
const contado = { type: SaleTypeEnum.CASH, externalProvider: null };
|
|
65
|
+
expect(isSureKeepFinanced(contado)).toBe(false);
|
|
66
|
+
expect(isExternallyFinanced(contado)).toBe(false);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare enum BenefitFlowEnum {
|
|
2
|
+
TOPUPS = "TOPUPS",
|
|
3
|
+
BILL_PAYMENT = "BILL_PAYMENT",
|
|
4
|
+
CREDIT = "CREDIT",
|
|
5
|
+
INSURANCE = "INSURANCE",
|
|
6
|
+
DONATION = "DONATION",
|
|
7
|
+
PHARMACY = "PHARMACY",
|
|
8
|
+
REMITTANCE = "REMITTANCE",
|
|
9
|
+
/** Fondeo de wallet PCF con efectivo via provider externo (Equality/Passport, OpenPay, …) — spec 13. */
|
|
10
|
+
WALLET_FUNDING = "WALLET_FUNDING"
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BenefitFlowEnum = void 0;
|
|
4
|
+
var BenefitFlowEnum;
|
|
5
|
+
(function (BenefitFlowEnum) {
|
|
6
|
+
BenefitFlowEnum["TOPUPS"] = "TOPUPS";
|
|
7
|
+
BenefitFlowEnum["BILL_PAYMENT"] = "BILL_PAYMENT";
|
|
8
|
+
BenefitFlowEnum["CREDIT"] = "CREDIT";
|
|
9
|
+
BenefitFlowEnum["INSURANCE"] = "INSURANCE";
|
|
10
|
+
BenefitFlowEnum["DONATION"] = "DONATION";
|
|
11
|
+
BenefitFlowEnum["PHARMACY"] = "PHARMACY";
|
|
12
|
+
BenefitFlowEnum["REMITTANCE"] = "REMITTANCE";
|
|
13
|
+
/** Fondeo de wallet PCF con efectivo via provider externo (Equality/Passport, OpenPay, …) — spec 13. */
|
|
14
|
+
BenefitFlowEnum["WALLET_FUNDING"] = "WALLET_FUNDING";
|
|
15
|
+
})(BenefitFlowEnum || (exports.BenefitFlowEnum = BenefitFlowEnum = {}));
|
|
@@ -102,7 +102,16 @@ export declare class PeopleResponse {
|
|
|
102
102
|
externalReferenceId: string | null;
|
|
103
103
|
SSN_ITINRequired: boolean | null;
|
|
104
104
|
hasSSN_ITIN: boolean | null;
|
|
105
|
+
/**
|
|
106
|
+
* @deprecated Typo histórico (tres `p`). NADIE escribe este campo:
|
|
107
|
+
* fiado-identity-lambda persiste `geoApproved` (una `p`), que es lo que
|
|
108
|
+
* está en DynamoDB. Quien lea este campo obtiene siempre `undefined`.
|
|
109
|
+
* Usar `geoApproved`. Se conserva solo para no romper a los consumidores
|
|
110
|
+
* que todavía lo referencian.
|
|
111
|
+
*/
|
|
105
112
|
geoAppproved?: boolean | null;
|
|
113
|
+
/** Geolocalización aprobada. `null` = no evaluada; solo `false` bloquea. */
|
|
114
|
+
geoApproved?: boolean | null;
|
|
106
115
|
cnbvManualApproval?: ManualApproval | null;
|
|
107
116
|
minorManualApproval?: ManualApproval | null;
|
|
108
117
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Con qué criterio se resolvió cuál archivo de S3 es la selfie del usuario.
|
|
3
|
+
* Le dice al consumidor qué tan confiable es el match antes de mandarla a un facematch.
|
|
4
|
+
*/
|
|
5
|
+
export declare enum SelfieSourceEnum {
|
|
6
|
+
/** Matcheó el verificationId de la verificación vigente en People. */
|
|
7
|
+
VERIFICATION = "VERIFICATION",
|
|
8
|
+
/** No hubo match por verificación: se tomó el archivo de selfie más reciente del bucket. */
|
|
9
|
+
LATEST = "LATEST"
|
|
10
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SelfieSourceEnum = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Con qué criterio se resolvió cuál archivo de S3 es la selfie del usuario.
|
|
6
|
+
* Le dice al consumidor qué tan confiable es el match antes de mandarla a un facematch.
|
|
7
|
+
*/
|
|
8
|
+
var SelfieSourceEnum;
|
|
9
|
+
(function (SelfieSourceEnum) {
|
|
10
|
+
/** Matcheó el verificationId de la verificación vigente en People. */
|
|
11
|
+
SelfieSourceEnum["VERIFICATION"] = "VERIFICATION";
|
|
12
|
+
/** No hubo match por verificación: se tomó el archivo de selfie más reciente del bucket. */
|
|
13
|
+
SelfieSourceEnum["LATEST"] = "LATEST";
|
|
14
|
+
})(SelfieSourceEnum || (exports.SelfieSourceEnum = SelfieSourceEnum = {}));
|
|
@@ -44,6 +44,23 @@ export interface ApplicationDefaults {
|
|
|
44
44
|
* UsernameAttributes del pool): true ⇒ pool con ['email','phone_number']. Heredado al tenant.
|
|
45
45
|
*/
|
|
46
46
|
allowSecondary?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* DEC-RBAC-111: política de contraseña que heredan los tenants creados desde esta aplicación.
|
|
49
|
+
*
|
|
50
|
+
* TOP-LEVEL (hermano de `autoregister`), NO dentro de `securityPolicy`: en la ficha del tenant
|
|
51
|
+
* ese sub-objeto lo reescribe entero el PUT de security-policy, y acá se mantiene la simetría.
|
|
52
|
+
*
|
|
53
|
+
* La herencia ocurre UNA sola vez, en el onboarding: cambiar este default después NO re-escribe
|
|
54
|
+
* la policy de los tenants ya creados, solo aplica a los futuros. Los 5 campos son opcionales;
|
|
55
|
+
* `tempValidityDays` no es per-tenant y por eso no está.
|
|
56
|
+
*/
|
|
57
|
+
passwordPolicy?: {
|
|
58
|
+
minLength?: number;
|
|
59
|
+
requireUppercase?: boolean;
|
|
60
|
+
requireLowercase?: boolean;
|
|
61
|
+
requireNumber?: boolean;
|
|
62
|
+
requireSymbol?: boolean;
|
|
63
|
+
};
|
|
47
64
|
}
|
|
48
65
|
export interface SeedRole {
|
|
49
66
|
roleId: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { TokenValidationMode } from '../enums/TokenValidationMode';
|
|
2
|
+
import { PasswordPolicyInput } from './PasswordPolicyInput';
|
|
2
3
|
/**
|
|
3
4
|
* Punto inicial de la política 2FA elegido en el alta del tenant (DEC-RBAC-064). Para el CREATE
|
|
4
5
|
* ambos campos son OPCIONALES: es un override del punto de partida — si se omite, el onboarding
|
|
@@ -47,4 +48,15 @@ export declare class CreateTenantRequest {
|
|
|
47
48
|
* onboarding hereda `app.defaults.securityPolicy`. Aditivo, no rompe altas existentes.
|
|
48
49
|
*/
|
|
49
50
|
securityPolicy?: CreateTenantSecurityPolicy;
|
|
51
|
+
/**
|
|
52
|
+
* DEC-RBAC-111: política de contraseña del tenant. Opcional: ausente ⇒ hereda
|
|
53
|
+
* `app.defaults.passwordPolicy` y, si tampoco está, la policy global del lambda.
|
|
54
|
+
*
|
|
55
|
+
* TOP-LEVEL a propósito, NO dentro de `securityPolicy`: ese sub-objeto lo reescribe entero el
|
|
56
|
+
* PUT de security-policy desde una lectura cacheada, y se llevaría puesta la passwordPolicy.
|
|
57
|
+
*
|
|
58
|
+
* INMUTABLE después del alta: alimenta la política nativa del user pool de Cognito, y no existe
|
|
59
|
+
* un update de pool (ver TD-RBAC-138 del platform-rbac-business).
|
|
60
|
+
*/
|
|
61
|
+
passwordPolicy?: PasswordPolicyInput;
|
|
50
62
|
}
|
|
@@ -13,6 +13,7 @@ exports.CreateTenantRequest = exports.CreateTenantSecurityPolicy = void 0;
|
|
|
13
13
|
const class_transformer_1 = require("class-transformer");
|
|
14
14
|
const class_validator_1 = require("class-validator");
|
|
15
15
|
const TokenValidationMode_1 = require("../enums/TokenValidationMode");
|
|
16
|
+
const PasswordPolicyInput_1 = require("./PasswordPolicyInput");
|
|
16
17
|
/**
|
|
17
18
|
* Punto inicial de la política 2FA elegido en el alta del tenant (DEC-RBAC-064). Para el CREATE
|
|
18
19
|
* ambos campos son OPCIONALES: es un override del punto de partida — si se omite, el onboarding
|
|
@@ -106,3 +107,10 @@ __decorate([
|
|
|
106
107
|
(0, class_transformer_1.Type)(() => CreateTenantSecurityPolicy),
|
|
107
108
|
__metadata("design:type", CreateTenantSecurityPolicy)
|
|
108
109
|
], CreateTenantRequest.prototype, "securityPolicy", void 0);
|
|
110
|
+
__decorate([
|
|
111
|
+
(0, class_transformer_1.Expose)(),
|
|
112
|
+
(0, class_validator_1.IsOptional)(),
|
|
113
|
+
(0, class_validator_1.ValidateNested)(),
|
|
114
|
+
(0, class_transformer_1.Type)(() => PasswordPolicyInput_1.PasswordPolicyInput),
|
|
115
|
+
__metadata("design:type", PasswordPolicyInput_1.PasswordPolicyInput)
|
|
116
|
+
], CreateTenantRequest.prototype, "passwordPolicy", void 0);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DEC-RBAC-111: política de complejidad de contraseña de un tenant.
|
|
3
|
+
*
|
|
4
|
+
* Los 5 campos son OPCIONALES: un campo ausente cae a la plantilla de la aplicación
|
|
5
|
+
* (`ApplicationDefaults.passwordPolicy`) y, de ahí, a la policy global del lambda.
|
|
6
|
+
*
|
|
7
|
+
* Se usa en dos lugares, siempre TOP-LEVEL (nunca dentro de `securityPolicy`):
|
|
8
|
+
* - `CreateTenantRequest.passwordPolicy` — override al crear el tenant.
|
|
9
|
+
* - `ApplicationDefaults.passwordPolicy` — default de la plantilla que el tenant hereda.
|
|
10
|
+
*
|
|
11
|
+
* `tempValidityDays` NO está acá a propósito: la validez de la contraseña temporal no es per-tenant
|
|
12
|
+
* (es el único campo de la policy que no afecta la fuerza de la contraseña). Sale siempre de la
|
|
13
|
+
* env var global del lambda.
|
|
14
|
+
*
|
|
15
|
+
* El rango 6..99 de `minLength` es el que admite `PasswordPolicy.MinimumLength` de Cognito. Se valida
|
|
16
|
+
* ACÁ para que un valor fuera de rango se rechace en el borde: si llegara a `CreateUserPool`, la
|
|
17
|
+
* `InvalidParameterException` caería con la ficha del tenant ya escrita en estado 'provisioning',
|
|
18
|
+
* o sea dentro de la rama de compensación de la saga de onboarding.
|
|
19
|
+
*
|
|
20
|
+
* OJO: acá NO se valida el PISO (que la policy no sea más débil que la global). Ese piso depende de
|
|
21
|
+
* env vars del lambda; declararlo también en el type-kit sería una segunda fuente de verdad, en otro
|
|
22
|
+
* repo, que driftea en cuanto alguien cambia la env var. Lo decide el lambda.
|
|
23
|
+
*/
|
|
24
|
+
export declare class PasswordPolicyInput {
|
|
25
|
+
minLength?: number;
|
|
26
|
+
requireUppercase?: boolean;
|
|
27
|
+
requireLowercase?: boolean;
|
|
28
|
+
requireNumber?: boolean;
|
|
29
|
+
requireSymbol?: boolean;
|
|
30
|
+
}
|
|
@@ -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
|
+
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.PasswordPolicyInput = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
/**
|
|
16
|
+
* DEC-RBAC-111: política de complejidad de contraseña de un tenant.
|
|
17
|
+
*
|
|
18
|
+
* Los 5 campos son OPCIONALES: un campo ausente cae a la plantilla de la aplicación
|
|
19
|
+
* (`ApplicationDefaults.passwordPolicy`) y, de ahí, a la policy global del lambda.
|
|
20
|
+
*
|
|
21
|
+
* Se usa en dos lugares, siempre TOP-LEVEL (nunca dentro de `securityPolicy`):
|
|
22
|
+
* - `CreateTenantRequest.passwordPolicy` — override al crear el tenant.
|
|
23
|
+
* - `ApplicationDefaults.passwordPolicy` — default de la plantilla que el tenant hereda.
|
|
24
|
+
*
|
|
25
|
+
* `tempValidityDays` NO está acá a propósito: la validez de la contraseña temporal no es per-tenant
|
|
26
|
+
* (es el único campo de la policy que no afecta la fuerza de la contraseña). Sale siempre de la
|
|
27
|
+
* env var global del lambda.
|
|
28
|
+
*
|
|
29
|
+
* El rango 6..99 de `minLength` es el que admite `PasswordPolicy.MinimumLength` de Cognito. Se valida
|
|
30
|
+
* ACÁ para que un valor fuera de rango se rechace en el borde: si llegara a `CreateUserPool`, la
|
|
31
|
+
* `InvalidParameterException` caería con la ficha del tenant ya escrita en estado 'provisioning',
|
|
32
|
+
* o sea dentro de la rama de compensación de la saga de onboarding.
|
|
33
|
+
*
|
|
34
|
+
* OJO: acá NO se valida el PISO (que la policy no sea más débil que la global). Ese piso depende de
|
|
35
|
+
* env vars del lambda; declararlo también en el type-kit sería una segunda fuente de verdad, en otro
|
|
36
|
+
* repo, que driftea en cuanto alguien cambia la env var. Lo decide el lambda.
|
|
37
|
+
*/
|
|
38
|
+
class PasswordPolicyInput {
|
|
39
|
+
}
|
|
40
|
+
exports.PasswordPolicyInput = PasswordPolicyInput;
|
|
41
|
+
__decorate([
|
|
42
|
+
(0, class_transformer_1.Expose)(),
|
|
43
|
+
(0, class_validator_1.IsOptional)(),
|
|
44
|
+
(0, class_validator_1.IsInt)(),
|
|
45
|
+
(0, class_validator_1.Min)(6),
|
|
46
|
+
(0, class_validator_1.Max)(99),
|
|
47
|
+
__metadata("design:type", Number)
|
|
48
|
+
], PasswordPolicyInput.prototype, "minLength", void 0);
|
|
49
|
+
__decorate([
|
|
50
|
+
(0, class_transformer_1.Expose)(),
|
|
51
|
+
(0, class_validator_1.IsOptional)(),
|
|
52
|
+
(0, class_validator_1.IsBoolean)(),
|
|
53
|
+
__metadata("design:type", Boolean)
|
|
54
|
+
], PasswordPolicyInput.prototype, "requireUppercase", void 0);
|
|
55
|
+
__decorate([
|
|
56
|
+
(0, class_transformer_1.Expose)(),
|
|
57
|
+
(0, class_validator_1.IsOptional)(),
|
|
58
|
+
(0, class_validator_1.IsBoolean)(),
|
|
59
|
+
__metadata("design:type", Boolean)
|
|
60
|
+
], PasswordPolicyInput.prototype, "requireLowercase", void 0);
|
|
61
|
+
__decorate([
|
|
62
|
+
(0, class_transformer_1.Expose)(),
|
|
63
|
+
(0, class_validator_1.IsOptional)(),
|
|
64
|
+
(0, class_validator_1.IsBoolean)(),
|
|
65
|
+
__metadata("design:type", Boolean)
|
|
66
|
+
], PasswordPolicyInput.prototype, "requireNumber", void 0);
|
|
67
|
+
__decorate([
|
|
68
|
+
(0, class_transformer_1.Expose)(),
|
|
69
|
+
(0, class_validator_1.IsOptional)(),
|
|
70
|
+
(0, class_validator_1.IsBoolean)(),
|
|
71
|
+
__metadata("design:type", Boolean)
|
|
72
|
+
], PasswordPolicyInput.prototype, "requireSymbol", void 0);
|
|
@@ -27,6 +27,7 @@ export * from './dtos/AuthorizeRequest';
|
|
|
27
27
|
export * from './dtos/AuthorizeResponse';
|
|
28
28
|
export * from './dtos/CreateTenantRequest';
|
|
29
29
|
export type { CreateTenantResponse } from './dtos/CreateTenantResponse';
|
|
30
|
+
export * from './dtos/PasswordPolicyInput';
|
|
30
31
|
export type { TenantStatus } from './dtos/TenantStatus';
|
|
31
32
|
export type { VerifyTenantInfraResponse } from './dtos/VerifyTenantInfraResponse';
|
|
32
33
|
export type { TenantDetailResponse } from './dtos/TenantDetailResponse';
|
|
@@ -63,6 +63,9 @@ __exportStar(require("./dtos/AuthorizeResponse"), exports);
|
|
|
63
63
|
// F-11 — onboarding de tenant (POST backoffice createTenant). CreateTenantRequest lleva
|
|
64
64
|
// decoradores class-validator → export de valor; CreateTenantResponse es interface → type-only.
|
|
65
65
|
__exportStar(require("./dtos/CreateTenantRequest"), exports);
|
|
66
|
+
// DEC-RBAC-111: policy de contraseña per-tenant. Lleva decoradores class-validator → export de valor.
|
|
67
|
+
// La consumen CreateTenantRequest (override del alta) y ApplicationDefaults (default de la plantilla).
|
|
68
|
+
__exportStar(require("./dtos/PasswordPolicyInput"), exports);
|
|
66
69
|
// MFA por tenant — methodsAllowed (value-set 'EMAIL'|'TOTP', TD-RBAC-071, DEC-095).
|
|
67
70
|
// UpdateTenantSecurityPolicyRequest lleva decoradores class-validator → export de valor;
|
|
68
71
|
// TenantSecurityPolicyResponse es interface plain → type-only.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { SaleExceptionTypeEnum } from '../enums/SaleExceptionTypeEnum';
|
|
2
|
+
import type { SaleExceptionStatusEnum } from '../enums/SaleExceptionStatusEnum';
|
|
3
|
+
import type { SaleExceptionEvent } from './SaleExceptionEvent';
|
|
4
|
+
import type { SaleExceptionPayload } from './SaleExceptionPayload';
|
|
5
|
+
/**
|
|
6
|
+
* Excepción de venta (`<T>RetailSaleException_GT`, pk `RETAILER#<retailerId>` ·
|
|
7
|
+
* sk `EXCEPTION#<createdAt>#<exceptionId>`, CERO GSIs). Bandeja del Admin VL, M6 §5.
|
|
8
|
+
* SureKeep Fase 3 — pista Retail.
|
|
9
|
+
*
|
|
10
|
+
* El `status` NO va en el sort key: el sk es inmutable en DynamoDB y el estado recorre
|
|
11
|
+
* `NEW → IN_REVIEW → APPROVED → APPLIED`. Meterlo ahí obligaría a borrar y reescribir el ítem en cada
|
|
12
|
+
* transición, perdiendo atomicidad y estabilidad del `exceptionId`. El filtro por estado se hace en
|
|
13
|
+
* memoria; son eventos raros.
|
|
14
|
+
*
|
|
15
|
+
* 🔴 **Hueco declarado (DEC-034):** `CAPTURE_FIX`, `BACKDATING` y `PRICE_OVERRIDE` mutan la venta
|
|
16
|
+
* después de cerrada, y el motor de comisiones solo escucha `SaleCompleted` / `SaleCancelled`. En el
|
|
17
|
+
* primer corte las excepciones **NO re-liquidan comisión**. Se ataca en F4 con un `SaleAmendedV1`.
|
|
18
|
+
*/
|
|
19
|
+
export interface SaleException {
|
|
20
|
+
exceptionId: string;
|
|
21
|
+
retailerId: string;
|
|
22
|
+
storeId: string;
|
|
23
|
+
/** `null` en las excepciones generales, que no cuelgan de una venta puntual. */
|
|
24
|
+
saleId: string | null;
|
|
25
|
+
type: SaleExceptionTypeEnum;
|
|
26
|
+
status: SaleExceptionStatusEnum;
|
|
27
|
+
/** userId de quien la levantó (normalmente el vendedor). */
|
|
28
|
+
requestedBy: string;
|
|
29
|
+
/** Nombre para mostrar, congelado al alta. `null` si no se pudo resolver. */
|
|
30
|
+
requestedByName: string | null;
|
|
31
|
+
/** ISO-8601. */
|
|
32
|
+
requestedAt: string;
|
|
33
|
+
/** OBLIGATORIA. Es lo que hace auditable la excepción. */
|
|
34
|
+
justification: string;
|
|
35
|
+
/**
|
|
36
|
+
* Impacto económico en centavos, con signo: positivo si la excepción suma (devolución al cliente,
|
|
37
|
+
* reemplazo), negativo si resta (descuento autorizado). `null` cuando no aplica.
|
|
38
|
+
*/
|
|
39
|
+
impactCents: number | null;
|
|
40
|
+
payload: SaleExceptionPayload;
|
|
41
|
+
/** userId del Admin VL que aprobó o rechazó. `null` mientras esté sin resolver. */
|
|
42
|
+
resolvedBy: string | null;
|
|
43
|
+
resolvedByName: string | null;
|
|
44
|
+
/** ISO-8601. `null` mientras esté sin resolver. */
|
|
45
|
+
resolvedAt: string | null;
|
|
46
|
+
/** Resolución OBLIGATORIA al aprobar o rechazar. `null` mientras esté sin resolver. */
|
|
47
|
+
resolution: string | null;
|
|
48
|
+
/** Hilo de solicitud, notas y resolución, en orden cronológico ascendente. */
|
|
49
|
+
timeline: SaleExceptionEvent[];
|
|
50
|
+
createdBy: string;
|
|
51
|
+
updatedBy: string;
|
|
52
|
+
createdAt: number;
|
|
53
|
+
updatedAt: number;
|
|
54
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { SaleExceptionEventKindEnum } from '../enums/SaleExceptionEventKindEnum';
|
|
2
|
+
/**
|
|
3
|
+
* Una entrada del timeline de una excepción: el hilo de solicitud, notas y resolución que la pantalla
|
|
4
|
+
* de Excepciones dibuja bajo la ficha. SureKeep Fase 3 — pista Retail.
|
|
5
|
+
*
|
|
6
|
+
* Va EMBEBIDO en el ítem de `RetailSaleException_GT`, no en una tabla aparte: son pocos eventos por
|
|
7
|
+
* excepción, se leen siempre junto con la ficha y nunca se consultan por su cuenta.
|
|
8
|
+
*/
|
|
9
|
+
export interface SaleExceptionEvent {
|
|
10
|
+
/** ISO-8601. */
|
|
11
|
+
at: string;
|
|
12
|
+
kind: SaleExceptionEventKindEnum;
|
|
13
|
+
/** userId del autor; `system` si lo escribió un proceso interno. */
|
|
14
|
+
authorId: string;
|
|
15
|
+
/** Nombre para mostrar, congelado al escribir el evento. `null` si no se pudo resolver. */
|
|
16
|
+
authorName: string | null;
|
|
17
|
+
body: string;
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lo que la excepción PIDE cambiar en la venta. Todos los campos son opcionales porque cada tipo usa
|
|
3
|
+
* los suyos: `CAPTURE_FIX` manda `sku`, `PRICE_OVERRIDE` manda `amountCents`, `BACKDATING` manda
|
|
4
|
+
* `soldAt`, `EXTENDED_WARRANTY` manda `imei`. `LATE_CANCEL` no manda ninguno.
|
|
5
|
+
* SureKeep Fase 3 — pista Retail.
|
|
6
|
+
*
|
|
7
|
+
* Es un shape TIPADO y no un objeto libre a propósito: el payload cruza el borde HTTP y un
|
|
8
|
+
* `Record<string, unknown>` ahí deja al front sin contrato y al validador sin nada que validar.
|
|
9
|
+
*/
|
|
10
|
+
export interface SaleExceptionPayload {
|
|
11
|
+
/** SKU correcto (CAPTURE_FIX). */
|
|
12
|
+
sku?: string;
|
|
13
|
+
/** Monto correcto en centavos (PRICE_OVERRIDE, CAPTURE_FIX). */
|
|
14
|
+
amountCents?: number;
|
|
15
|
+
/** Fecha real de la venta, ISO-8601 (BACKDATING). */
|
|
16
|
+
soldAt?: string;
|
|
17
|
+
/** IMEI del equipo de reemplazo (EXTENDED_WARRANTY). */
|
|
18
|
+
imei?: string;
|
|
19
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Un campo que cambió en una acción auditada. `from` ausente en un alta. */
|
|
2
|
+
export interface SaleLogChange {
|
|
3
|
+
field: string;
|
|
4
|
+
from: string | null;
|
|
5
|
+
to: string | null;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Una entrada del tab «Bitácora» del drawer de una venta. Proyección de `SharedAuditTrail_GT`
|
|
9
|
+
* (`pk = ENTITY#SALE#<saleId>`, `sk = TS#<iso>#<ulid>`, orden cronológico nativo).
|
|
10
|
+
* SureKeep Fase 3 — pista Retail.
|
|
11
|
+
*
|
|
12
|
+
* El diff viaja APLANADO en `changes` y no como los objetos `old`/`new` crudos de la tabla: la
|
|
13
|
+
* pantalla dibuja una lista de «campo: antes → después», y un objeto libre en el contrato obligaría al
|
|
14
|
+
* front a adivinar la forma. Los valores se serializan a string por eso mismo.
|
|
15
|
+
*
|
|
16
|
+
* ⚠️ `changes` NUNCA lleva PII: la tabla de auditoría solo guarda identificadores y valores
|
|
17
|
+
* operacionales (status, storeId, type…). Ver `fiado-logging`.
|
|
18
|
+
*/
|
|
19
|
+
export interface SaleLogEntry {
|
|
20
|
+
/** ISO-8601 del momento de la acción (sale del `sk`). */
|
|
21
|
+
at: string;
|
|
22
|
+
/** Acción auditada: `SALE_COMPLETE`, `SALE_CANCEL`, `PAYMENT_REGISTERED`… */
|
|
23
|
+
action: string;
|
|
24
|
+
/** Actor: userId del AuthContext, o `system` si la disparó un proceso interno. */
|
|
25
|
+
performedBy: string;
|
|
26
|
+
/** Motivo, cuando la acción lo exige (cancelación, excepción aplicada). */
|
|
27
|
+
reason: string | null;
|
|
28
|
+
changes: SaleLogChange[];
|
|
29
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { SalesReportIdEnum } from '../enums/SalesReportIdEnum';
|
|
2
|
+
import type { ReportPeriodicityEnum } from '../enums/ReportPeriodicityEnum';
|
|
3
|
+
import type { ReportFormatEnum } from '../enums/ReportFormatEnum';
|
|
4
|
+
/**
|
|
5
|
+
* Un reporte del catálogo del Admin VL (M6 §5.1). Es CONFIGURACIÓN, no una fila de tabla: el catálogo
|
|
6
|
+
* de los 5 reportes vive en código y no se persiste — cambia con un deploy, no con un write.
|
|
7
|
+
* SureKeep Fase 3 — pista Retail.
|
|
8
|
+
*/
|
|
9
|
+
export interface SalesReportDefinition {
|
|
10
|
+
reportId: SalesReportIdEnum;
|
|
11
|
+
/** Nombre para mostrar, en español mexicano. */
|
|
12
|
+
name: string;
|
|
13
|
+
description: string;
|
|
14
|
+
periodicity: ReportPeriodicityEnum;
|
|
15
|
+
formats: ReportFormatEnum[];
|
|
16
|
+
/** Referencia al documento de negocio que lo define (ej. `M6 §5.1`). */
|
|
17
|
+
reference: string;
|
|
18
|
+
/** ISO-8601 de la última corrida conocida; `null` si nunca corrió. */
|
|
19
|
+
lastRunAt: string | null;
|
|
20
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { SalesReportIdEnum } from '../enums/SalesReportIdEnum';
|
|
2
|
+
import type { ReportFormatEnum } from '../enums/ReportFormatEnum';
|
|
3
|
+
import type { ReportRunStatusEnum } from '../enums/ReportRunStatusEnum';
|
|
4
|
+
/**
|
|
5
|
+
* Una corrida de reporte (`<T>RetailReportRun_GT`, pk `RETAILER#<retailerId>` ·
|
|
6
|
+
* sk `RUN#<requestedAt>#<runId>`, CERO GSIs). Es el log de la sección 3 de la pantalla de Reportes.
|
|
7
|
+
* SureKeep Fase 3 — pista Retail.
|
|
8
|
+
*
|
|
9
|
+
* La generación es ASÍNCRONA: el `POST .../run` persiste la corrida en `QUEUED` y devuelve el `runId`;
|
|
10
|
+
* el front poletea `GET /backoffice/reports`. API Gateway corta a los 29 s y un reporte de red
|
|
11
|
+
* completa no entra en una respuesta síncrona.
|
|
12
|
+
*/
|
|
13
|
+
export interface SalesReportRun {
|
|
14
|
+
runId: string;
|
|
15
|
+
retailerId: string;
|
|
16
|
+
reportId: SalesReportIdEnum;
|
|
17
|
+
format: ReportFormatEnum;
|
|
18
|
+
status: ReportRunStatusEnum;
|
|
19
|
+
/** userId de quien la disparó; `system` si la lanzó el cron. */
|
|
20
|
+
requestedBy: string;
|
|
21
|
+
requestedByName: string | null;
|
|
22
|
+
/** ISO-8601. Es parte del sort key: ordena el log de corridas. */
|
|
23
|
+
requestedAt: string;
|
|
24
|
+
/** ISO-8601 del fin de la generación. `null` mientras no termine. */
|
|
25
|
+
completedAt: string | null;
|
|
26
|
+
/** Ventana de datos del reporte, ISO-8601. */
|
|
27
|
+
periodFrom: string | null;
|
|
28
|
+
periodTo: string | null;
|
|
29
|
+
/** Filas generadas. `null` mientras no termine. */
|
|
30
|
+
rowCount: number | null;
|
|
31
|
+
/** URL prefirmada de descarga. Solo con `status: READY`; `null` en cualquier otro estado. */
|
|
32
|
+
downloadUrl: string | null;
|
|
33
|
+
/** Por qué falló. Solo con `status: FAILED`. */
|
|
34
|
+
failureReason: string | null;
|
|
35
|
+
createdBy: string;
|
|
36
|
+
updatedBy: string;
|
|
37
|
+
createdAt: number;
|
|
38
|
+
updatedAt: number;
|
|
39
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* POST /backoffice/sales/:saleId/cancel — cancelación del Admin VL. SureKeep Fase 3 — pista Retail.
|
|
3
|
+
*
|
|
4
|
+
* Es un endpoint SEPARADO de `POST /sales/:saleId/cancel` (el del vendedor), no una rama del mismo, y
|
|
5
|
+
* por eso lleva su propio DTO. Son dos reglas de negocio distintas: la del vendedor está acotada a su
|
|
6
|
+
* propia venta y a la ventana de 7 días; la del admin puede cancelar FUERA de ventana — que es justo
|
|
7
|
+
* lo que habilita la excepción `LATE_CANCEL`. Mezclarlas en un handler enredaría las dos.
|
|
8
|
+
*
|
|
9
|
+
* `outOfWindowExceptionId` es el puente entre las dos piezas: cancelar fuera de ventana exige una
|
|
10
|
+
* excepción `LATE_CANCEL` ya aprobada. Sin ella el manager rechaza, aunque el actor tenga el permiso.
|
|
11
|
+
*/
|
|
12
|
+
export declare class BackofficeCancelSaleRequest {
|
|
13
|
+
reason: string;
|
|
14
|
+
/**
|
|
15
|
+
* Confirmación de que el equipo se verificó físicamente en tienda. Ausente y `false` se tratan
|
|
16
|
+
* igual (fail-closed): el manager responde `412 IMEI_NOT_RETURNABLE`, que es la respuesta
|
|
17
|
+
* semánticamente correcta y no un error de forma. `@IsBoolean()` estricto — el string `"false"` se
|
|
18
|
+
* rechaza en vez de colarse como truthy.
|
|
19
|
+
*/
|
|
20
|
+
equipmentVerified?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Excepción `LATE_CANCEL` aprobada que autoriza cancelar fuera de la ventana. Solo se exige cuando
|
|
23
|
+
* la venta YA está fuera de ventana; dentro de ventana se ignora.
|
|
24
|
+
*/
|
|
25
|
+
outOfWindowExceptionId?: string;
|
|
26
|
+
}
|