@fiado/type-kit 3.278.0 → 3.280.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.
Files changed (82) hide show
  1. package/bin/collection/dtos/CollectionAttemptDto.d.ts +15 -0
  2. package/bin/collection/dtos/CollectionAttemptDto.js +63 -0
  3. package/bin/collection/dtos/CollectionErrorLogDto.d.ts +12 -0
  4. package/bin/collection/dtos/CollectionErrorLogDto.js +54 -0
  5. package/bin/collection/dtos/CollectionIntentDetailDto.d.ts +10 -0
  6. package/bin/collection/dtos/CollectionIntentDetailDto.js +40 -0
  7. package/bin/collection/dtos/CollectionIntentSummaryDto.d.ts +22 -0
  8. package/bin/collection/dtos/CollectionIntentSummaryDto.js +94 -0
  9. package/bin/collection/dtos/CollectionMetricsDto.d.ts +9 -0
  10. package/bin/collection/dtos/CollectionMetricsDto.js +41 -0
  11. package/bin/collection/dtos/CollectionOutboxEventDto.d.ts +15 -0
  12. package/bin/collection/dtos/CollectionOutboxEventDto.js +56 -0
  13. package/bin/collection/index.d.ts +6 -0
  14. package/bin/collection/index.js +7 -0
  15. package/bin/index.d.ts +1 -0
  16. package/bin/index.js +6 -2
  17. package/bin/retailCommission/dtos/CommissionAccrual.d.ts +78 -0
  18. package/bin/retailCommission/dtos/CommissionAccrual.js +2 -0
  19. package/bin/retailCommission/dtos/CommissionApi.d.ts +169 -0
  20. package/bin/retailCommission/dtos/CommissionApi.js +2 -0
  21. package/bin/retailCommission/dtos/CommissionCalcTrace.d.ts +73 -0
  22. package/bin/retailCommission/dtos/CommissionCalcTrace.js +2 -0
  23. package/bin/retailCommission/dtos/CommissionPayout.d.ts +73 -0
  24. package/bin/retailCommission/dtos/CommissionPayout.js +2 -0
  25. package/bin/retailCommission/dtos/CommissionPlan.d.ts +182 -0
  26. package/bin/retailCommission/dtos/CommissionPlan.js +2 -0
  27. package/bin/retailCommission/enums/CommissionAccrualStatusEnum.d.ts +14 -0
  28. package/bin/retailCommission/enums/CommissionAccrualStatusEnum.js +18 -0
  29. package/bin/retailCommission/enums/CommissionCalcStepEnum.d.ts +23 -0
  30. package/bin/retailCommission/enums/CommissionCalcStepEnum.js +27 -0
  31. package/bin/retailCommission/enums/CommissionExceptionTypeEnum.d.ts +14 -0
  32. package/bin/retailCommission/enums/CommissionExceptionTypeEnum.js +18 -0
  33. package/bin/retailCommission/enums/CommissionMechanicTypeEnum.d.ts +24 -0
  34. package/bin/retailCommission/enums/CommissionMechanicTypeEnum.js +28 -0
  35. package/bin/retailCommission/enums/CommissionPayeeTypeEnum.d.ts +13 -0
  36. package/bin/retailCommission/enums/CommissionPayeeTypeEnum.js +17 -0
  37. package/bin/retailCommission/enums/CommissionPayoutStatusEnum.d.ts +18 -0
  38. package/bin/retailCommission/enums/CommissionPayoutStatusEnum.js +22 -0
  39. package/bin/retailCommission/enums/CommissionPeriodTypeEnum.d.ts +17 -0
  40. package/bin/retailCommission/enums/CommissionPeriodTypeEnum.js +21 -0
  41. package/bin/retailCommission/enums/CommissionPlanStatusEnum.d.ts +14 -0
  42. package/bin/retailCommission/enums/CommissionPlanStatusEnum.js +18 -0
  43. package/bin/retailCommission/enums/CommissionPriceReferenceEnum.d.ts +18 -0
  44. package/bin/retailCommission/enums/CommissionPriceReferenceEnum.js +22 -0
  45. package/bin/retailCommission/enums/CommissionQuotaMeasureEnum.d.ts +12 -0
  46. package/bin/retailCommission/enums/CommissionQuotaMeasureEnum.js +16 -0
  47. package/bin/retailCommission/enums/CommissionQuotaModeEnum.d.ts +13 -0
  48. package/bin/retailCommission/enums/CommissionQuotaModeEnum.js +17 -0
  49. package/bin/retailCommission/enums/CommissionQuotaSubjectEnum.d.ts +12 -0
  50. package/bin/retailCommission/enums/CommissionQuotaSubjectEnum.js +16 -0
  51. package/bin/retailCommission/enums/CommissionQuotaTypeEnum.d.ts +12 -0
  52. package/bin/retailCommission/enums/CommissionQuotaTypeEnum.js +16 -0
  53. package/bin/retailCommission/index.d.ts +18 -0
  54. package/bin/retailCommission/index.js +37 -0
  55. package/package.json +1 -1
  56. package/src/collection/dtos/CollectionAttemptDto.ts +17 -0
  57. package/src/collection/dtos/CollectionErrorLogDto.ts +14 -0
  58. package/src/collection/dtos/CollectionIntentDetailDto.ts +13 -0
  59. package/src/collection/dtos/CollectionIntentSummaryDto.ts +24 -0
  60. package/src/collection/dtos/CollectionMetricsDto.ts +11 -0
  61. package/src/collection/dtos/CollectionOutboxEventDto.ts +17 -0
  62. package/src/collection/index.ts +8 -0
  63. package/src/index.ts +4 -0
  64. package/src/retailCommission/dtos/CommissionAccrual.ts +81 -0
  65. package/src/retailCommission/dtos/CommissionApi.ts +205 -0
  66. package/src/retailCommission/dtos/CommissionCalcTrace.ts +64 -0
  67. package/src/retailCommission/dtos/CommissionPayout.ts +76 -0
  68. package/src/retailCommission/dtos/CommissionPlan.ts +199 -0
  69. package/src/retailCommission/enums/CommissionAccrualStatusEnum.ts +14 -0
  70. package/src/retailCommission/enums/CommissionCalcStepEnum.ts +23 -0
  71. package/src/retailCommission/enums/CommissionExceptionTypeEnum.ts +14 -0
  72. package/src/retailCommission/enums/CommissionMechanicTypeEnum.ts +24 -0
  73. package/src/retailCommission/enums/CommissionPayeeTypeEnum.ts +13 -0
  74. package/src/retailCommission/enums/CommissionPayoutStatusEnum.ts +18 -0
  75. package/src/retailCommission/enums/CommissionPeriodTypeEnum.ts +17 -0
  76. package/src/retailCommission/enums/CommissionPlanStatusEnum.ts +14 -0
  77. package/src/retailCommission/enums/CommissionPriceReferenceEnum.ts +18 -0
  78. package/src/retailCommission/enums/CommissionQuotaMeasureEnum.ts +12 -0
  79. package/src/retailCommission/enums/CommissionQuotaModeEnum.ts +13 -0
  80. package/src/retailCommission/enums/CommissionQuotaSubjectEnum.ts +12 -0
  81. package/src/retailCommission/enums/CommissionQuotaTypeEnum.ts +12 -0
  82. package/src/retailCommission/index.ts +23 -0
@@ -0,0 +1,169 @@
1
+ import type { CommissionPlanStatusEnum } from '../enums/CommissionPlanStatusEnum';
2
+ import type { CommissionPayoutStatusEnum } from '../enums/CommissionPayoutStatusEnum';
3
+ import type { CommissionAddOn, CommissionCategory, CommissionPlanSnapshot, CommissionQuota } from './CommissionPlan';
4
+ import type { CommissionAccrual, CommissionSaleInput } from './CommissionAccrual';
5
+ import type { CommissionAdjustment, CommissionPayout, CommissionPayoutSeller } from './CommissionPayout';
6
+ /**
7
+ * Los contratos HTTP del motor de comisiones — uno por endpoint, sin reutilizar.
8
+ * SureKeep Fase 3 — pista Retail.
9
+ *
10
+ * ⚠️ **El `retailerId` NO aparece en ningún request.** Sale siempre del token: el silo aísla por
11
+ * *tenant*, no por *retailer*, y SureKeep tiene varios. Si un request lo mandara, se ignoraría — pero
12
+ * la mejor forma de que no se ignore mal es que no exista el campo.
13
+ */
14
+ /**
15
+ * `GET /backoffice/commissions/plan`
16
+ *
17
+ * `active: null` es un estado legítimo, no un 404: una cadena recién dada de alta todavía no publicó
18
+ * su primer plan. Devolver 404 obligaría al front a tratar el arranque normal como excepción, y esa
19
+ * rama solo se ejercita el primer día de cada cadena — o sea, nunca se prueba.
20
+ */
21
+ export interface GetCommissionPlanResponse {
22
+ active: CommissionPlanSnapshot | null;
23
+ draft: CommissionPlanSnapshot | null;
24
+ }
25
+ /** `GET /backoffice/commissions/plan/snapshots` — solo cabeceras, sin el contenido del plan. */
26
+ export interface CommissionPlanSnapshotSummary {
27
+ snapshotId: string;
28
+ status: CommissionPlanStatusEnum;
29
+ effectiveFrom: string;
30
+ publishedBy: string | null;
31
+ publishedAt: string | null;
32
+ changeNote: string | null;
33
+ /**
34
+ * Calculado contra el puntero `ACTIVE`, **nunca desde `status`**.
35
+ *
36
+ * Son dos registros del mismo hecho: `status` son N ítems y el puntero es uno solo. Si alguna vez
37
+ * se desincronizan, el puntero es el que no puede mentir. `status` viaja igual para que la
38
+ * discrepancia se VEA en la respuesta en vez de quedar escondida.
39
+ */
40
+ active: boolean;
41
+ }
42
+ export interface ListPlanSnapshotsResponse {
43
+ snapshots: CommissionPlanSnapshotSummary[];
44
+ nextCursor: string | null;
45
+ }
46
+ /** `GET /backoffice/commissions/plan/snapshots/{snapshotId}` — el plan completo de una versión vieja. */
47
+ export interface GetPlanSnapshotResponse {
48
+ snapshot: CommissionPlanSnapshot;
49
+ }
50
+ /**
51
+ * `PUT /backoffice/commissions/plan/draft`
52
+ *
53
+ * Se manda el documento COMPLETO, no el pedazo editado: `sk = DRAFT` es un ítem único y un `put`
54
+ * entero es una escritura atómica, sin merge del lado del servidor. Los 7 modales de la pantalla
55
+ * pegan a este mismo endpoint.
56
+ */
57
+ export interface UpdatePlanDraftRequest {
58
+ /**
59
+ * El `updatedAt` que el editor tenía al cargar. Control de concurrencia optimista.
60
+ *
61
+ * Sin él, dos admins editando a la vez terminan en last-write-wins silencioso: el segundo pisa
62
+ * al primero, y el primero se entera cuando ve que su excepción desapareció. `null` solo cuando
63
+ * todavía no existe borrador.
64
+ */
65
+ expectedUpdatedAt: string | null;
66
+ categories: CommissionCategory[];
67
+ quotas: CommissionQuota[];
68
+ addOns: CommissionAddOn[];
69
+ storeOverrideBps: Record<string, number>;
70
+ effectiveFrom: string;
71
+ }
72
+ export interface UpdatePlanDraftResponse {
73
+ draft: CommissionPlanSnapshot;
74
+ updatedAt: string;
75
+ }
76
+ /**
77
+ * `POST /backoffice/commissions/plan/publish`
78
+ *
79
+ * El `changeNote` se pide ACÁ y no al guardar: la nota describe qué cambió **en esta versión**, y eso
80
+ * solo se sabe al sellarla. Pedirla en cada guardado sería pedirle al admin que justifique cada click.
81
+ */
82
+ export interface PublishPlanRequest {
83
+ changeNote: string;
84
+ /** El `snapshotId` que el editor cree vigente. `null` en la PRIMERA publicación de la cadena. */
85
+ expectedActiveSnapshotId: string | null;
86
+ }
87
+ export interface PublishPlanResponse {
88
+ snapshotId: string;
89
+ publishedAt: string;
90
+ }
91
+ /**
92
+ * `POST /backoffice/commissions/plan/simulate`
93
+ *
94
+ * Contra un periodo real YA CERRADO. Un corte en curso daría un número que cambia con cada venta y
95
+ * que el Admin leería como predicción.
96
+ */
97
+ export interface SimulatePlanRequest {
98
+ periodId: string;
99
+ }
100
+ export interface SimulatePlanSellerResult {
101
+ sellerId: string;
102
+ wouldPayCents: number;
103
+ currentPlanCents: number;
104
+ deltaCents: number;
105
+ }
106
+ export interface SimulatePlanResponse {
107
+ periodId: string;
108
+ totalCents: number;
109
+ /**
110
+ * 🔑 **El número que importa.** Un total de $184 000 no dice nada solo; «$12 400 más que el plan
111
+ * vigente» es una decisión.
112
+ */
113
+ vsCurrentPlanCents: number;
114
+ salesEvaluated: number;
115
+ /**
116
+ * `true` si el periodo tenía más ventas que el tope del data lake (10 000 filas).
117
+ *
118
+ * Un total de dinero calculado sobre filas truncadas **sin decirlo** es peor que un error: se ve
119
+ * exacto y no lo es.
120
+ */
121
+ truncated: boolean;
122
+ bySeller: SimulatePlanSellerResult[];
123
+ }
124
+ /** `GET /backoffice/commissions/payouts` */
125
+ export interface ListPayoutsResponse {
126
+ payouts: CommissionPayout[];
127
+ nextCursor: string | null;
128
+ }
129
+ /** `GET /backoffice/commissions/payouts/{periodId}` — una sola Query trae las tres cosas. */
130
+ export interface GetPayoutResponse {
131
+ payout: CommissionPayout;
132
+ sellers: CommissionPayoutSeller[];
133
+ adjustments: CommissionAdjustment[];
134
+ }
135
+ /** `GET /backoffice/commissions/payouts/{periodId}/sellers/{sellerId}` */
136
+ export interface GetPayoutSellerResponse {
137
+ seller: CommissionPayoutSeller;
138
+ accruals: CommissionAccrual[];
139
+ }
140
+ /**
141
+ * `POST /backoffice/commissions/payouts/{periodId}/adjustments`
142
+ *
143
+ * La única escritura de dinero sin una venta detrás. Va con header `Idempotency-Key`.
144
+ */
145
+ export interface CreateAdjustmentRequest {
146
+ sellerId: string;
147
+ /** Puede ser negativo. */
148
+ amountCents: number;
149
+ /** Obligatorio: un movimiento de dinero sin motivo no se puede auditar. */
150
+ reason: string;
151
+ saleId: string | null;
152
+ date: string;
153
+ }
154
+ export interface CreateAdjustmentResponse {
155
+ adjustment: CommissionAdjustment;
156
+ }
157
+ /**
158
+ * `POST /backoffice/commissions/payouts/{periodId}/close`
159
+ *
160
+ * Responde **202**, no 200: con 200 vendedores y 3 000 devengos el trabajo son ~200 Queries más ~120
161
+ * BatchWrites, y API Gateway corta a los 29 segundos. No es una preferencia de diseño: no cabe.
162
+ */
163
+ export interface ClosePayoutResponse {
164
+ periodId: string;
165
+ status: CommissionPayoutStatusEnum;
166
+ startedAt: string;
167
+ }
168
+ /** Lo que el simulador reconstruye desde el data lake para volver a correr el motor. */
169
+ export type CommissionSimulationSale = CommissionSaleInput;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,73 @@
1
+ import type { CommissionCalcStepEnum } from '../enums/CommissionCalcStepEnum';
2
+ import type { CommissionExceptionTypeEnum } from '../enums/CommissionExceptionTypeEnum';
3
+ /**
4
+ * La traza de cálculo: el paso a paso de por qué un vendedor cobró ese monto.
5
+ * SureKeep Fase 3 — pista Retail.
6
+ *
7
+ * 🔴 **Es una unión CERRADA por `step`, no un mapa abierto.** Cada variante declara exactamente qué
8
+ * campos lleva su `detail`, y ninguno es libre.
9
+ *
10
+ * La razón es de PII: la traza se persiste junto al devengo y viaja a la pantalla de desglose, así
11
+ * que es el vehículo más probable de fuga de datos del comprador. **Sin campos libres no hay dónde
12
+ * meterlos.** Tipar el `detail` como `Record<string, unknown>` sería llamarlo whitelist sin
13
+ * implementarla — un control afirmado y no aplicado es peor que uno ausente.
14
+ *
15
+ * Sin traza no se puede explicar un monto, y explicar un monto es exactamente lo que hace falta
16
+ * cuando alguien reclama su comisión.
17
+ */
18
+ export type CommissionCalcTraceEntry = {
19
+ step: CommissionCalcStepEnum.MECHANIC;
20
+ label: string;
21
+ outputCents: number;
22
+ detail: {
23
+ categoryId: string;
24
+ mechanicType: string;
25
+ };
26
+ } | {
27
+ step: CommissionCalcStepEnum.EXCEPTION;
28
+ label: string;
29
+ outputCents: number;
30
+ detail: {
31
+ exceptionId: string;
32
+ matchedOn: CommissionExceptionTypeEnum;
33
+ };
34
+ } | {
35
+ step: CommissionCalcStepEnum.ADDON;
36
+ label: string;
37
+ outputCents: number;
38
+ detail: {
39
+ addOnId: string;
40
+ };
41
+ } | {
42
+ step: CommissionCalcStepEnum.QUOTA;
43
+ label: string;
44
+ inputCents: number;
45
+ outputCents: number;
46
+ detail: {
47
+ quotaId: string;
48
+ met: boolean;
49
+ factorBps: number;
50
+ };
51
+ } | {
52
+ step: CommissionCalcStepEnum.ADJUSTMENT;
53
+ label: string;
54
+ outputCents: number;
55
+ detail: {
56
+ adjustmentId: string;
57
+ };
58
+ } | {
59
+ /**
60
+ * El SKU no matcheó ninguna categoría del plan.
61
+ *
62
+ * Devenga 0 y queda VISIBLE en el corte, en vez de mandarse a la DLQ. Un mensaje en la DLQ
63
+ * no lo mira nadie hasta que hay un reclamo; una fila en 0 la ve quien revisa el corte.
64
+ */
65
+ step: CommissionCalcStepEnum.NO_CATEGORY;
66
+ label: string;
67
+ outputCents: number;
68
+ detail: {
69
+ sku: string;
70
+ brand: string | null;
71
+ };
72
+ };
73
+ export type CommissionCalcTrace = CommissionCalcTraceEntry[];
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,73 @@
1
+ import type { CommissionPayoutStatusEnum } from '../enums/CommissionPayoutStatusEnum';
2
+ /**
3
+ * El corte semanal y todo lo que cuelga de él.
4
+ * SureKeep Fase 3 — pista Retail.
5
+ *
6
+ * Los tres tipos de ítem viven en la misma partición del retailer y se separan por el sort key
7
+ * (`…#META`, `…#ADJ#<id>`, `…#SELLER#<id>`), así que **una sola Query trae el corte completo**:
8
+ * totales, ajustes y roster.
9
+ *
10
+ * El sufijo `#META` no es decorativo: sin él, un `between` por rango de semanas arrastraría también
11
+ * los ajustes y el roster de cada corte y rompería la paginación.
12
+ */
13
+ export interface CommissionPayout {
14
+ retailerId: string;
15
+ periodId: string;
16
+ periodStart: string;
17
+ periodEnd: string;
18
+ status: CommissionPayoutStatusEnum;
19
+ /** Suma de los devengos liquidados. Se sella al cerrar. */
20
+ grossCents: number | null;
21
+ /** Suma de los ajustes manuales, con signo. */
22
+ adjustmentsCents: number | null;
23
+ netCents: number | null;
24
+ sellerCount: number | null;
25
+ accrualCount: number | null;
26
+ closedBy: string | null;
27
+ closedAt: string | null;
28
+ }
29
+ /**
30
+ * El roster: un ítem por vendedor con devengos en el corte, escrito AL DEVENGAR.
31
+ *
32
+ * 🔑 **Es lo que hace el cierre autocontenido.** El fan-out itera este roster, no la lista que
33
+ * devuelva `retail-org-business`. Un vendedor dado de baja, transferido o creado a mitad de semana
34
+ * sigue acá — si el fan-out saliera del padrón, sus devengos nunca pasarían a `PAID`, nunca entrarían
35
+ * al total, y nadie se enteraría.
36
+ *
37
+ * Los dos contadores se acumulan con `ADD` al devengar. Son lo que permite pintar el desglose de un
38
+ * corte ABIERTO sin barrer todos los devengos en cada carga de pantalla.
39
+ */
40
+ export interface CommissionPayoutSeller {
41
+ retailerId: string;
42
+ periodId: string;
43
+ sellerId: string;
44
+ accruedCount: number;
45
+ baseAmountCents: number;
46
+ /** Al cerrar: lo que efectivamente se le liquidó. */
47
+ settledAmountCents: number | null;
48
+ /** Al cerrar: si alcanzó su cuota. */
49
+ quotaMet: boolean | null;
50
+ quotaFactorBps: number | null;
51
+ }
52
+ /**
53
+ * Un ajuste manual sobre el corte.
54
+ *
55
+ * Es la **única escritura de dinero sin una venta que la respalde**, y por eso es la única operación
56
+ * del motor con guard de idempotencia. El devengo no lo necesita: su clave es determinista.
57
+ */
58
+ export interface CommissionAdjustment {
59
+ retailerId: string;
60
+ periodId: string;
61
+ adjustmentId: string;
62
+ sellerId: string;
63
+ date: string;
64
+ /** El ticket al que se refiere, si aplica. */
65
+ saleId: string | null;
66
+ /** **Puede ser negativo.** Una reversa de un corte ya cerrado entra como ajuste negativo. */
67
+ amountCents: number;
68
+ /** Obligatorio. Un movimiento de dinero sin motivo no se puede auditar. */
69
+ reason: string;
70
+ /** Email de quien lo hizo, o `system` en los automáticos por cancelación. */
71
+ author: string;
72
+ createdAt: string;
73
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,182 @@
1
+ import type { CommissionMechanicTypeEnum } from '../enums/CommissionMechanicTypeEnum';
2
+ import type { CommissionPlanStatusEnum } from '../enums/CommissionPlanStatusEnum';
3
+ import type { CommissionPriceReferenceEnum } from '../enums/CommissionPriceReferenceEnum';
4
+ import type { CommissionQuotaTypeEnum } from '../enums/CommissionQuotaTypeEnum';
5
+ import type { CommissionQuotaMeasureEnum } from '../enums/CommissionQuotaMeasureEnum';
6
+ import type { CommissionQuotaSubjectEnum } from '../enums/CommissionQuotaSubjectEnum';
7
+ import type { CommissionQuotaModeEnum } from '../enums/CommissionQuotaModeEnum';
8
+ import type { CommissionPeriodTypeEnum } from '../enums/CommissionPeriodTypeEnum';
9
+ import type { CommissionExceptionTypeEnum } from '../enums/CommissionExceptionTypeEnum';
10
+ /**
11
+ * El plan de comisiones de VentasLuga, versionado por snapshot inmutable.
12
+ * SureKeep Fase 3 — pista Retail.
13
+ *
14
+ * Todo lo de este archivo vive DENTRO de un snapshot: se congela al publicar y no se vuelve a tocar.
15
+ * Esa es la razón de que hasta las reglas de `sku → categoría` (`CommissionCategoryMatch`) vivan acá
16
+ * y no en el código del motor — si vivieran en el código, un redespliegue cambiaría montos ya
17
+ * devengados y dos accruals del mismo snapshot podrían calcularse distinto.
18
+ *
19
+ * Montos en centavos (`*Cents`), porcentajes en puntos base (`*Bps`, 10000 = 100%).
20
+ */
21
+ /**
22
+ * Un par de valores: sin cuota y con cuota.
23
+ *
24
+ * ⚠️ **No es un descuento: son dos tablas de precios.** Alcanzar la cuota no «suma un bono», elige
25
+ * columna. Por eso `base: 0, withQuota: 2500` (PayJoy) es válido y significa «solo comisiona si
26
+ * alcanzó la cuota», no un error de captura.
27
+ */
28
+ export interface CommissionValuePair {
29
+ /** Valor cuando NO se alcanzó la cuota. Puede ser 0. */
30
+ base: number;
31
+ /** Valor cuando SÍ se alcanzó. Puede ser igual al base si la categoría no discrimina. */
32
+ withQuota: number;
33
+ }
34
+ /** Un tramo de precio del equipo. Los tramos no se solapan y cubren de 0 a infinito. */
35
+ export interface CommissionPriceTier extends CommissionValuePair {
36
+ /** Etiqueta visible: `D`, `C`, `B`, `A`. */
37
+ grade: string;
38
+ minCents: number;
39
+ /** `null` = sin tope superior (el tramo más alto). */
40
+ maxCents: number | null;
41
+ }
42
+ /** Una celda de la matriz, identificada por sus coordenadas. */
43
+ export interface CommissionMatrixCell extends CommissionValuePair {
44
+ /** Un valor por dimensión, en el mismo orden que `dimensions`. */
45
+ coords: string[];
46
+ }
47
+ /** Una variante enumerada (un plan de pospago, por ejemplo). */
48
+ export interface CommissionVariant extends CommissionValuePair {
49
+ variantId: string;
50
+ label: string;
51
+ }
52
+ /** Una variante por forma de pago. Los valores van en bps. */
53
+ export interface CommissionPaymentVariant extends CommissionValuePair {
54
+ /** `CASH` | `CREDIT` — cómo pagó el cliente. */
55
+ paymentType: string;
56
+ label: string;
57
+ }
58
+ /**
59
+ * La mecánica de una categoría, discriminada por `type`.
60
+ *
61
+ * `PRICE_TIER`, `FLAT`, `MATRIX` y `VARIANT` pagan en CENTAVOS; `PERCENT` y `PERCENT_BY_PAYMENT`
62
+ * pagan en BPS sobre el precio. Esa distinción la resuelve el evaluador con `valueKind`, no una rama
63
+ * por tipo.
64
+ */
65
+ export type CommissionMechanic = {
66
+ type: CommissionMechanicTypeEnum.PRICE_TIER;
67
+ tiers: CommissionPriceTier[];
68
+ } | {
69
+ type: CommissionMechanicTypeEnum.FLAT;
70
+ value: CommissionValuePair;
71
+ } | {
72
+ type: CommissionMechanicTypeEnum.PERCENT;
73
+ value: CommissionValuePair;
74
+ } | {
75
+ type: CommissionMechanicTypeEnum.MATRIX;
76
+ dimensions: string[];
77
+ cells: CommissionMatrixCell[];
78
+ } | {
79
+ type: CommissionMechanicTypeEnum.VARIANT;
80
+ variants: CommissionVariant[];
81
+ } | {
82
+ type: CommissionMechanicTypeEnum.PERCENT_BY_PAYMENT;
83
+ variants: CommissionPaymentVariant[];
84
+ };
85
+ /** Un nivel del acelerador. `factorBps` 10000 = 1.0×, 12000 = 1.2×. */
86
+ export interface CommissionQuotaLevel {
87
+ minAmountCents: number;
88
+ factorBps: number;
89
+ }
90
+ /**
91
+ * Una cuota. Binaria (un gate) o escalonada (N niveles con multiplicador).
92
+ *
93
+ * ⚠️ **Todas se resuelven al CERRAR el periodo**, nunca al devengar. Ese es el diseño de Jaime y es
94
+ * lo que evita el mecanismo más peligroso posible: reescribir filas ya devengadas cada vez que una
95
+ * venta nueva mueve el conteo.
96
+ */
97
+ export interface CommissionQuota {
98
+ quotaId: string;
99
+ name: string;
100
+ description: string | null;
101
+ active: boolean;
102
+ type: CommissionQuotaTypeEnum;
103
+ measure: CommissionQuotaMeasureEnum;
104
+ subject: CommissionQuotaSubjectEnum;
105
+ period: CommissionPeriodTypeEnum;
106
+ mode: CommissionQuotaModeEnum;
107
+ /** Solo `BINARY`. El umbral a alcanzar, en la unidad de `measure`. */
108
+ threshold: number | null;
109
+ /** Solo `TIERED`. Ordenados de menor a mayor. */
110
+ levels: CommissionQuotaLevel[] | null;
111
+ /** Si el valor `withQuota` REEMPLAZA al base (`true`) o se suma. Hoy siempre `true`. */
112
+ replacesBase: boolean;
113
+ }
114
+ /**
115
+ * Cómo se decide que una venta pertenece a esta categoría.
116
+ *
117
+ * Vive DENTRO del snapshot (versionado e inmutable con el plan). Si viviera en el código del motor,
118
+ * cambiar el mapa reescribiría el pasado.
119
+ */
120
+ export interface CommissionCategoryMatch {
121
+ skus: string[];
122
+ brands: string[];
123
+ /** Prefijos de SKU, para familias completas. */
124
+ skuPrefixes: string[];
125
+ }
126
+ /**
127
+ * Una excepción: un SKU o una marca que paga distinto que su categoría.
128
+ *
129
+ * Precedencia: **SKU gana sobre BRAND, y BRAND sobre la mecánica.**
130
+ */
131
+ export interface CommissionException {
132
+ exceptionId: string;
133
+ type: CommissionExceptionTypeEnum;
134
+ /** El SKU exacto o el nombre de la marca, según `type`. */
135
+ target: string;
136
+ label: string;
137
+ value: CommissionValuePair;
138
+ }
139
+ /** Una categoría de producto con su mecánica, su cuota y sus excepciones. */
140
+ export interface CommissionCategory {
141
+ categoryId: string;
142
+ name: string;
143
+ icon: string | null;
144
+ description: string | null;
145
+ match: CommissionCategoryMatch;
146
+ /** `null` = la categoría NO está condicionada a ninguna cuota (Pospago, Zmotos). */
147
+ quotaId: string | null;
148
+ priceReference: CommissionPriceReferenceEnum;
149
+ mechanic: CommissionMechanic;
150
+ exceptions: CommissionException[];
151
+ }
152
+ /** Un add-on: monto fijo que se suma FUERA del stacking y fuera del máximo. */
153
+ export interface CommissionAddOn {
154
+ addOnId: string;
155
+ label: string;
156
+ amountCents: number;
157
+ active: boolean;
158
+ }
159
+ /**
160
+ * Una versión del plan. Publicada es inmutable; el borrador se pisa.
161
+ *
162
+ * `storeOverrideBps` es un **pago a OTRA persona** (el admin de la tienda) sobre las ventas de su
163
+ * equipo. Se modela pero **no se devenga** en el primer corte, hasta que se defina quién es ese
164
+ * admin en `retail-org-business`.
165
+ */
166
+ export interface CommissionPlanSnapshot {
167
+ retailerId: string;
168
+ /** `null` mientras es borrador: el ULID se asigna al publicar. */
169
+ snapshotId: string | null;
170
+ status: CommissionPlanStatusEnum;
171
+ effectiveFrom: string;
172
+ categories: CommissionCategory[];
173
+ quotas: CommissionQuota[];
174
+ addOns: CommissionAddOn[];
175
+ /** `storeId` → bps adicionales para el admin de esa tienda. */
176
+ storeOverrideBps: Record<string, number>;
177
+ changeNote: string | null;
178
+ publishedBy: string | null;
179
+ publishedAt: string | null;
180
+ updatedAt: string | null;
181
+ updatedBy: string | null;
182
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Estado de una fila de devengo.
3
+ *
4
+ * ACCRUED - Devengada con su monto base. La cuota y el factor TODAVÍA no están resueltos.
5
+ * PAID - Liquidada al cerrar el corte: ya tiene `quotaMet`, `quotaFactorBps` y `settledAmountCents`.
6
+ * REVERSED - Revertida por cancelación de la venta, con el corte aún abierto.
7
+ *
8
+ * SureKeep Fase 3 — pista Retail. Motor de comisiones de VentasLuga.
9
+ */
10
+ export declare enum CommissionAccrualStatusEnum {
11
+ ACCRUED = "ACCRUED",
12
+ PAID = "PAID",
13
+ REVERSED = "REVERSED"
14
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CommissionAccrualStatusEnum = void 0;
4
+ /**
5
+ * Estado de una fila de devengo.
6
+ *
7
+ * ACCRUED - Devengada con su monto base. La cuota y el factor TODAVÍA no están resueltos.
8
+ * PAID - Liquidada al cerrar el corte: ya tiene `quotaMet`, `quotaFactorBps` y `settledAmountCents`.
9
+ * REVERSED - Revertida por cancelación de la venta, con el corte aún abierto.
10
+ *
11
+ * SureKeep Fase 3 — pista Retail. Motor de comisiones de VentasLuga.
12
+ */
13
+ var CommissionAccrualStatusEnum;
14
+ (function (CommissionAccrualStatusEnum) {
15
+ CommissionAccrualStatusEnum["ACCRUED"] = "ACCRUED";
16
+ CommissionAccrualStatusEnum["PAID"] = "PAID";
17
+ CommissionAccrualStatusEnum["REVERSED"] = "REVERSED";
18
+ })(CommissionAccrualStatusEnum || (exports.CommissionAccrualStatusEnum = CommissionAccrualStatusEnum = {}));
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Los pasos que puede registrar la traza de cálculo.
3
+ *
4
+ * La traza es una unión CERRADA por este enum, sin campos libres: es el vehículo más probable de
5
+ * fuga de PII del comprador y no debe haber dónde meterla.
6
+ *
7
+ * MECHANIC - Se evaluó la mecánica de la categoría.
8
+ * EXCEPTION - Una excepción por SKU o marca reemplazó el valor de la mecánica.
9
+ * ADDON - Se sumó un add-on. Van FUERA del stacking.
10
+ * QUOTA - Se resolvió la cuota (binaria o escalonada). Ocurre al CERRAR, no al devengar.
11
+ * ADJUSTMENT - Un ajuste manual del corte.
12
+ * NO_CATEGORY - El SKU no matcheó ninguna categoría del plan: devenga 0 y queda visible.
13
+ *
14
+ * SureKeep Fase 3 — pista Retail. Motor de comisiones de VentasLuga.
15
+ */
16
+ export declare enum CommissionCalcStepEnum {
17
+ MECHANIC = "MECHANIC",
18
+ EXCEPTION = "EXCEPTION",
19
+ ADDON = "ADDON",
20
+ QUOTA = "QUOTA",
21
+ ADJUSTMENT = "ADJUSTMENT",
22
+ NO_CATEGORY = "NO_CATEGORY"
23
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CommissionCalcStepEnum = void 0;
4
+ /**
5
+ * Los pasos que puede registrar la traza de cálculo.
6
+ *
7
+ * La traza es una unión CERRADA por este enum, sin campos libres: es el vehículo más probable de
8
+ * fuga de PII del comprador y no debe haber dónde meterla.
9
+ *
10
+ * MECHANIC - Se evaluó la mecánica de la categoría.
11
+ * EXCEPTION - Una excepción por SKU o marca reemplazó el valor de la mecánica.
12
+ * ADDON - Se sumó un add-on. Van FUERA del stacking.
13
+ * QUOTA - Se resolvió la cuota (binaria o escalonada). Ocurre al CERRAR, no al devengar.
14
+ * ADJUSTMENT - Un ajuste manual del corte.
15
+ * NO_CATEGORY - El SKU no matcheó ninguna categoría del plan: devenga 0 y queda visible.
16
+ *
17
+ * SureKeep Fase 3 — pista Retail. Motor de comisiones de VentasLuga.
18
+ */
19
+ var CommissionCalcStepEnum;
20
+ (function (CommissionCalcStepEnum) {
21
+ CommissionCalcStepEnum["MECHANIC"] = "MECHANIC";
22
+ CommissionCalcStepEnum["EXCEPTION"] = "EXCEPTION";
23
+ CommissionCalcStepEnum["ADDON"] = "ADDON";
24
+ CommissionCalcStepEnum["QUOTA"] = "QUOTA";
25
+ CommissionCalcStepEnum["ADJUSTMENT"] = "ADJUSTMENT";
26
+ CommissionCalcStepEnum["NO_CATEGORY"] = "NO_CATEGORY";
27
+ })(CommissionCalcStepEnum || (exports.CommissionCalcStepEnum = CommissionCalcStepEnum = {}));
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Sobre qué aplica una excepción del plan.
3
+ *
4
+ * Precedencia: SKU gana sobre BRAND, y BRAND sobre la mecánica de la categoría.
5
+ *
6
+ * SKU - Un SKU exacto.
7
+ * BRAND - Una marca completa.
8
+ *
9
+ * SureKeep Fase 3 — pista Retail. Motor de comisiones de VentasLuga.
10
+ */
11
+ export declare enum CommissionExceptionTypeEnum {
12
+ SKU = "SKU",
13
+ BRAND = "BRAND"
14
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CommissionExceptionTypeEnum = void 0;
4
+ /**
5
+ * Sobre qué aplica una excepción del plan.
6
+ *
7
+ * Precedencia: SKU gana sobre BRAND, y BRAND sobre la mecánica de la categoría.
8
+ *
9
+ * SKU - Un SKU exacto.
10
+ * BRAND - Una marca completa.
11
+ *
12
+ * SureKeep Fase 3 — pista Retail. Motor de comisiones de VentasLuga.
13
+ */
14
+ var CommissionExceptionTypeEnum;
15
+ (function (CommissionExceptionTypeEnum) {
16
+ CommissionExceptionTypeEnum["SKU"] = "SKU";
17
+ CommissionExceptionTypeEnum["BRAND"] = "BRAND";
18
+ })(CommissionExceptionTypeEnum || (exports.CommissionExceptionTypeEnum = CommissionExceptionTypeEnum = {}));
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Las 6 formas de calcular la comisión de una categoría (D12).
3
+ *
4
+ * Son el producto cartesiano de dos ejes —cómo se elige la celda y en qué unidad paga— y por eso
5
+ * un solo evaluador las cubre todas: `toCells(mechanic)` normaliza cualquiera a
6
+ * `[{ match, baseValue, withQuotaValue }]` + `valueKind`.
7
+ *
8
+ * PRICE_TIER - Por rango de precio del equipo (D/C/B/A). Equipos.
9
+ * FLAT - Monto fijo por unidad. MiFi, PayJoy.
10
+ * PERCENT - Porcentaje del precio, en bps. Accesorios.
11
+ * MATRIX - Celda por N dimensiones. SIMs: operador × origen.
12
+ * VARIANT - Monto por variante enumerada. Pospago: plan $339 → $220.
13
+ * PERCENT_BY_PAYMENT - Porcentaje según forma de pago. Zmotos: contado 2% / crédito 4%.
14
+ *
15
+ * SureKeep Fase 3 — pista Retail. Motor de comisiones de VentasLuga.
16
+ */
17
+ export declare enum CommissionMechanicTypeEnum {
18
+ PRICE_TIER = "PRICE_TIER",
19
+ FLAT = "FLAT",
20
+ PERCENT = "PERCENT",
21
+ MATRIX = "MATRIX",
22
+ VARIANT = "VARIANT",
23
+ PERCENT_BY_PAYMENT = "PERCENT_BY_PAYMENT"
24
+ }