sinfactura-types 1.6.20 → 1.6.22

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/README.md CHANGED
@@ -74,7 +74,14 @@ This re-resolves the git ref to the latest commit on `dist` and pins it in the l
74
74
 
75
75
  > **Why explicit?** `yarn install` does NOT re-resolve git branch refs to their current HEAD — it reuses the cached resolution for reproducibility. Consumers that want auto-bump-on-pull can add a `post-merge` Husky hook that runs `yarn up sinfactura-types@github:sinfactura/types#dist` whenever `package.json`/`yarn.lock` changed in the merge.
76
76
 
77
- ## Legacy: Publishing a New NPM Version
77
+ ## Publishing
78
+
79
+ See [`PUBLISHING.md`](./PUBLISHING.md) for the full release workflow — when to
80
+ bump the version, the `dist`-branch and npm channels, the PR checklist, and how
81
+ to coordinate a cross-repo rollout. Per-release summaries live in
82
+ [`CHANGELOG.md`](./CHANGELOG.md).
83
+
84
+ ### Legacy: Publishing a New NPM Version
78
85
 
79
86
  Kept for reference / external consumers. New SINFACTURA repos should use the git URL instead.
80
87
 
package/dist/account.d.ts CHANGED
@@ -12,6 +12,23 @@ declare global {
12
12
  debit?: number;
13
13
  credit?: number;
14
14
  amount?: number;
15
+ /**
16
+ * catalogId (api#942, lowercase e.g. `'ars'`/`'usd-oficial'`) — FK
17
+ * to PlatformCurrency. Promoted from the api#945 module augmentation
18
+ * (app#1539 / ADR-0013).
19
+ *
20
+ * DENOMINATION CONTRACT: this row's money values (`amount`/`credit`/
21
+ * `debit`/`balance`) are denominated in the catalogId named here.
22
+ * When `currency` is ABSENT — which is ≈all legacy/historical rows —
23
+ * the row is denominated in `store.config.displayCurrency` as it was
24
+ * at write time, and consumers MUST fall back to it. NEVER infer the
25
+ * denomination from `customer.currencyId`: that field is a
26
+ * display/pricing preference (passenger data server-side), and
27
+ * mislabeling unstamped rows by it is the root cause of api#1333.
28
+ *
29
+ * 6 legacy rows carry a raw uppercase ISO `'ARS'` (pre-#1137);
30
+ * being normalized to catalogId in api#1350.
31
+ */
15
32
  currency?: string;
16
33
  currencyValue?: number;
17
34
  currencyValueAt?: number;
package/dist/auth.d.ts CHANGED
@@ -12,6 +12,7 @@ declare global {
12
12
  cuit: string;
13
13
  fullName: string;
14
14
  phone?: string;
15
+ acknowledgedSharedCuit?: boolean;
15
16
  }
16
17
  interface Recover {
17
18
  email: string;
@@ -45,6 +45,17 @@ declare global {
45
45
  salt?: string;
46
46
  search: string;
47
47
  updatedAt?: number;
48
+ /**
49
+ * catalogId (api#942) — FK to PlatformCurrency.
50
+ *
51
+ * DISPLAY / PRICING preference only: which currency this customer
52
+ * views and transacts in (load-bearing in storefront pricing + the
53
+ * DNI/CUIT checkout gate). It is NOT a ledger denomination and is
54
+ * pure passenger data server-side. MUST NOT be used to infer the
55
+ * denomination of unstamped `ACCOUNT` rows — doing so is the root
56
+ * cause of api#1333. Unstamped ledger rows fall back to
57
+ * `store.config.displayCurrency`, never to this field.
58
+ */
48
59
  currencyId?: string;
49
60
  deliveryAddress?: {
50
61
  fullName: string;
package/dist/demo.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Demo environment types (sinfactura/types#33, part of sinfactura/app#1054).
3
+ *
4
+ * Custom JWT claims minted for anonymous public demo sessions
5
+ * (test.sinfactura.com) and in-app demo tenants. The `readOnly` flag is
6
+ * enforced server-side via the `requireWritable` gate (ADR-0010 / api#870);
7
+ * see also `Store.type === 'demo'` in store.ts.
8
+ */
9
+ declare global {
10
+ /**
11
+ * Firebase custom claims attached to a demo session token. The presence of
12
+ * `demo: true` marks the session as a demo tenant.
13
+ */
14
+ interface DemoClaims {
15
+ /** Always `true` — discriminates a demo session from a real one. */
16
+ demo: true;
17
+ /** Tenant the demo session is scoped to. */
18
+ storeId: string;
19
+ /** When true, all writes are blocked (view-only demo). */
20
+ readOnly: boolean;
21
+ }
22
+ }
23
+ export {};
package/dist/demo.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Demo environment types (sinfactura/types#33, part of sinfactura/app#1054).
3
+ *
4
+ * Custom JWT claims minted for anonymous public demo sessions
5
+ * (test.sinfactura.com) and in-app demo tenants. The `readOnly` flag is
6
+ * enforced server-side via the `requireWritable` gate (ADR-0010 / api#870);
7
+ * see also `Store.type === 'demo'` in store.ts.
8
+ */
9
+ export {};
package/dist/index.d.ts CHANGED
@@ -9,6 +9,7 @@ export * from "./cash";
9
9
  export * from "./categories";
10
10
  export * from "./currency";
11
11
  export * from "./customer";
12
+ export * from "./demo";
12
13
  export * from "./imports";
13
14
  export * from "./invoice";
14
15
  export * from "./log";
@@ -19,6 +20,8 @@ export * from "./order";
19
20
  export * from "./payment";
20
21
  export * from "./product";
21
22
  export * from "./return";
23
+ export * from "./serviceOrder";
24
+ export * from "./serviceTemplate";
22
25
  export * from "./stock";
23
26
  export * from "./store";
24
27
  export * from "./storefrontEvent";
package/dist/index.js CHANGED
@@ -9,6 +9,7 @@ export * from "./cash";
9
9
  export * from "./categories";
10
10
  export * from "./currency";
11
11
  export * from "./customer";
12
+ export * from "./demo";
12
13
  export * from "./imports";
13
14
  export * from "./invoice";
14
15
  export * from "./log";
@@ -19,6 +20,8 @@ export * from "./order";
19
20
  export * from "./payment";
20
21
  export * from "./product";
21
22
  export * from "./return";
23
+ export * from "./serviceOrder";
24
+ export * from "./serviceTemplate";
22
25
  export * from "./stock";
23
26
  export * from "./store";
24
27
  export * from "./storefrontEvent";
package/dist/invoice.d.ts CHANGED
@@ -34,6 +34,10 @@ declare global {
34
34
  caeExpiration: string;
35
35
  observations?: string;
36
36
  fiscalStatus?: FiscalStatus;
37
+ serviceStartDate?: number;
38
+ serviceEndDate?: number;
39
+ paymentDueDate?: number;
40
+ serviceOrderId?: string;
37
41
  }
38
42
  interface InvoiceItem {
39
43
  code: string;
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Service order types — repair / installation / maintenance / diagnosis
3
+ * workflows ("Órdenes de Servicio").
4
+ *
5
+ * Phase 1 Foundation for the Services Feature (sinfactura/app#758,
6
+ * sinfactura/types#30). A ServiceOrder is a parallel entity to the
7
+ * product-sales Order pipeline: multi-stage workflow, technician assignment,
8
+ * equipment intake, parts consumption, and AFIP concept=2 service invoicing.
9
+ *
10
+ * Companion: ServiceTemplate (serviceTemplate.ts, sinfactura/types#31) defines
11
+ * per-type default configuration that seeds new orders.
12
+ */
13
+ declare global {
14
+ /** Kind of service. Drives which workflow stages apply (see ServiceTemplate). */
15
+ type ServiceType = 'repair' | 'installation' | 'maintenance' | 'diagnosis';
16
+ /**
17
+ * Workflow stage of a service order. The canonical full repair pipeline is
18
+ * received → diagnosing → quoted → approved → in_progress → testing → ready →
19
+ * delivered, plus the terminal `cancelled`. Simpler service types skip stages
20
+ * (configured per `ServiceTemplate.requiredStages`).
21
+ */
22
+ type ServiceStatus = 'received' | 'diagnosing' | 'quoted' | 'approved' | 'in_progress' | 'testing' | 'ready' | 'delivered' | 'cancelled';
23
+ /** Operator-set urgency, used for Kanban ordering and SLA hints. */
24
+ type ServicePriority = 'low' | 'normal' | 'high' | 'urgent';
25
+ /**
26
+ * How the service is priced.
27
+ * - `flat` — single fixed price.
28
+ * - `hourly` — labor billed by the hour (`laborRate` × hours).
29
+ * - `parts_labor` — parts at cost/markup + labor.
30
+ * - `diagnostic` — fixed diagnostic fee.
31
+ * - `warranty` — no charge (covered under warranty).
32
+ */
33
+ type PricingModel = 'flat' | 'hourly' | 'parts_labor' | 'diagnostic' | 'warranty';
34
+ /** A single inventory part consumed on a service order. */
35
+ interface PartUsed {
36
+ productId: string;
37
+ sku: string;
38
+ name: string;
39
+ quantity: number;
40
+ unitCost: number;
41
+ total: number;
42
+ }
43
+ /** A technician work session logged against a service order (manual hours at V1). */
44
+ interface WorkLog {
45
+ workLogId: string;
46
+ technicianId: string;
47
+ /** Unix ms of the work session. */
48
+ date: number;
49
+ /** Hours worked in this session. */
50
+ hours: number;
51
+ description: string;
52
+ partsUsed?: PartUsed[];
53
+ }
54
+ /** One entry in a service order's status history (append-only audit trail). */
55
+ interface ServiceStatusEntry {
56
+ status: ServiceStatus;
57
+ /** Unix ms when the transition happened. */
58
+ timestamp: number;
59
+ /** User who triggered the transition. */
60
+ userId: string;
61
+ notes?: string;
62
+ }
63
+ /**
64
+ * Core service-order entity. Parallel to `Order` but with a multi-stage
65
+ * workflow, equipment intake, technician assignment, and service-specific
66
+ * pricing. Stored in its own DynamoDB partition (sinfactura/api#637).
67
+ */
68
+ interface ServiceOrder {
69
+ storeId: string;
70
+ serviceOrderId: string;
71
+ /** Human-facing sequential ticket number shown to the customer. */
72
+ ticketNumber: string;
73
+ customerId: string;
74
+ serviceType: ServiceType;
75
+ /** FK to the `ServiceTemplate` this order was created from, if any. */
76
+ templateId?: string;
77
+ priority: ServicePriority;
78
+ status: ServiceStatus;
79
+ statusHistory: ServiceStatusEntry[];
80
+ /** When true the order is paused (waiting on parts, customer, etc.). */
81
+ onHold: boolean;
82
+ equipment?: {
83
+ type?: string;
84
+ brand?: string;
85
+ model?: string;
86
+ serialNumber?: string;
87
+ /** Accessories received with the equipment (charger, case, …). */
88
+ accessories?: string[];
89
+ /** Cosmetic / functional condition noted at intake. */
90
+ condition?: string;
91
+ /** Customer-reported fault. */
92
+ reportedIssue?: string;
93
+ };
94
+ diagnosis?: {
95
+ notes: string;
96
+ diagnosedBy?: string;
97
+ /** Unix ms. */
98
+ diagnosedAt?: number;
99
+ };
100
+ quote?: {
101
+ pricingModel: PricingModel;
102
+ laborCost?: number;
103
+ partsCost?: number;
104
+ amount: number;
105
+ /** Unix ms when the quote was presented to the customer. */
106
+ quotedAt?: number;
107
+ /** Set once the customer approves / rejects. */
108
+ approved?: boolean;
109
+ approvedBy?: string;
110
+ approvedAt?: number;
111
+ };
112
+ technicianId?: string;
113
+ /** Unix ms the order was assigned. */
114
+ assignedAt?: number;
115
+ workLogs: WorkLog[];
116
+ partsUsed: PartUsed[];
117
+ pricingModel: PricingModel;
118
+ laborRate?: number;
119
+ laborCost?: number;
120
+ partsCost?: number;
121
+ discount?: number;
122
+ total?: number;
123
+ /**
124
+ * Self-describing currency catalogId stamp (see the currency taxonomy in
125
+ * `currency.ts`). Absent rows fall back to `store.config.displayCurrency`.
126
+ */
127
+ currency?: string;
128
+ createdAt: number;
129
+ updatedAt: number;
130
+ /** Promised completion / pickup date shown to the customer. */
131
+ promisedAt?: number;
132
+ deliveredAt?: number;
133
+ invoiceId?: string;
134
+ warrantyDays?: number;
135
+ /** Unix ms the warranty expires (stamped at delivery). */
136
+ warrantyExpiresAt?: number;
137
+ }
138
+ }
139
+ export {};
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Service order types — repair / installation / maintenance / diagnosis
3
+ * workflows ("Órdenes de Servicio").
4
+ *
5
+ * Phase 1 Foundation for the Services Feature (sinfactura/app#758,
6
+ * sinfactura/types#30). A ServiceOrder is a parallel entity to the
7
+ * product-sales Order pipeline: multi-stage workflow, technician assignment,
8
+ * equipment intake, parts consumption, and AFIP concept=2 service invoicing.
9
+ *
10
+ * Companion: ServiceTemplate (serviceTemplate.ts, sinfactura/types#31) defines
11
+ * per-type default configuration that seeds new orders.
12
+ */
13
+ export {};
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Service template types — pre-defined per-service-type configuration for the
3
+ * Services Feature (sinfactura/app#758, sinfactura/types#31).
4
+ *
5
+ * A ServiceTemplate seeds defaults onto a new ServiceOrder: which workflow
6
+ * stages are mandatory, default pricing model / rates, QA checklists, and
7
+ * common parts auto-populated on intake. Shares the ServiceType / ServiceStatus
8
+ * / PricingModel unions defined in serviceOrder.ts.
9
+ */
10
+ declare global {
11
+ /** A single QA checklist item on a service template. */
12
+ interface ServiceChecklistItem {
13
+ step: string;
14
+ description?: string;
15
+ required: boolean;
16
+ }
17
+ /** A commonly-used part auto-populated onto orders created from the template. */
18
+ interface ServiceCommonPart {
19
+ productId: string;
20
+ name: string;
21
+ quantity: number;
22
+ }
23
+ /**
24
+ * Pre-defined configuration for a service type. Defines the default workflow,
25
+ * pricing, checklists, and common parts for orders created from it. One per
26
+ * (storeId, templateId).
27
+ */
28
+ interface ServiceTemplate {
29
+ storeId: string;
30
+ templateId: string;
31
+ /** Display name, e.g. "Reparación de motor eléctrico". */
32
+ name: string;
33
+ description: string;
34
+ serviceType: ServiceType;
35
+ categoryId?: string;
36
+ /** Which workflow stages are mandatory for orders using this template. */
37
+ requiredStages: ServiceStatus[];
38
+ /** Auto-proceed without quote approval. */
39
+ skipQuote: boolean;
40
+ /** Whether equipment intake is needed. */
41
+ requiresEquipment: boolean;
42
+ estimatedHours: number;
43
+ basePrice: number;
44
+ pricingModel: PricingModel;
45
+ laborRate?: number;
46
+ warrantyDays?: number;
47
+ checklist: ServiceChecklistItem[];
48
+ commonParts: ServiceCommonPart[];
49
+ disabled: boolean;
50
+ }
51
+ }
52
+ export {};
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Service template types — pre-defined per-service-type configuration for the
3
+ * Services Feature (sinfactura/app#758, sinfactura/types#31).
4
+ *
5
+ * A ServiceTemplate seeds defaults onto a new ServiceOrder: which workflow
6
+ * stages are mandatory, default pricing model / rates, QA checklists, and
7
+ * common parts auto-populated on intake. Shares the ServiceType / ServiceStatus
8
+ * / PricingModel unions defined in serviceOrder.ts.
9
+ */
10
+ export {};
package/dist/store.d.ts CHANGED
@@ -4,10 +4,6 @@ declare global {
4
4
  fiscalConditions: FiscalCondition[];
5
5
  ivaTypes: Method[];
6
6
  minWithDni: number;
7
- notificationOptions: {
8
- id: string;
9
- name: string;
10
- }[];
11
7
  stats: {
12
8
  store: number;
13
9
  };
@@ -105,6 +101,7 @@ declare global {
105
101
  interface Store {
106
102
  storeId: string;
107
103
  createdAt: number;
104
+ type?: 'production' | 'demo';
108
105
  name: string;
109
106
  address: {
110
107
  street: string;
@@ -115,6 +112,7 @@ declare global {
115
112
  cuit: string;
116
113
  phone: string;
117
114
  email: string;
115
+ acknowledgedSharedCuit?: boolean;
118
116
  config: {
119
117
  priceDecimals: 0 | 1 | 2 | 3;
120
118
  stock: boolean;
@@ -124,6 +122,12 @@ declare global {
124
122
  * the operator's screens are framed in — distinct from the
125
123
  * currency of any individual money entity (Order / Invoice /
126
124
  * etc carry their own self-describing `currency` stamps).
125
+ *
126
+ * NOTE: the self-describing-stamp invariant is true for Order /
127
+ * Invoice but only ASPIRATIONAL for ACCOUNT — `Account.currency`
128
+ * is optional and ≈100% of historical rows are unstamped, so they
129
+ * fall back to THIS field for their denomination (tracked
130
+ * api#1333 / api#1352).
127
131
  */
128
132
  displayCurrency?: string;
129
133
  /**
@@ -173,13 +177,13 @@ declare global {
173
177
  fiscalConditions: FiscalCondition[];
174
178
  ivaTypes: Method[];
175
179
  minWithDni: number;
176
- notificationOptions?: Method[];
177
180
  maintenance?: MaintenanceInfo;
178
181
  legacyCurrencyIds?: Record<number, string>;
179
182
  }
180
183
  interface StoreIntegrations {
181
184
  afip?: Afip;
182
185
  mercadopago?: Mercadopago;
186
+ whatsapp?: WhatsAppConfig;
183
187
  }
184
188
  type FxAutoUpdateStrategy = "overwrite" | "overwrite-if-stale" | "notify-only";
185
189
  interface FxAutoUpdateBinding {
package/dist/user.d.ts CHANGED
@@ -29,6 +29,13 @@ declare global {
29
29
  enrolledAt?: number;
30
30
  lastUsedAt?: number;
31
31
  lastCounter?: number;
32
+ recoveryCodes?: {
33
+ hash: string;
34
+ usedAt?: number;
35
+ }[];
36
+ recoveryCodesGeneratedAt?: number;
37
+ failedAttempts?: number;
38
+ lockedUntil?: number;
32
39
  };
33
40
  }
34
41
  type UserNotifications = Partial<Record<NotificationTypeEnum, boolean>>;
@@ -11,7 +11,7 @@ declare global {
11
11
  }
12
12
  interface UserLoggedInEvent extends UserActivityEventBase {
13
13
  event: 'User Logged In';
14
- method: 'password' | 'totp' | 'refresh' | 'social';
14
+ method: 'password' | 'totp' | 'refresh' | 'social' | 'recovery';
15
15
  }
16
16
  interface UserLoggedOutEvent extends UserActivityEventBase {
17
17
  event: 'User Logged Out';
@@ -35,6 +35,11 @@ declare global {
35
35
  event: 'Two-Factor Reset';
36
36
  target_user_id: string;
37
37
  }
38
+ interface TwoFactorRecoveryCodesGeneratedEvent extends UserActivityEventBase {
39
+ event: 'Two-Factor Recovery Codes Generated';
40
+ count: number;
41
+ trigger: 'enrollment' | 'regenerate';
42
+ }
38
43
  interface StorePaletteChangedEvent extends UserActivityEventBase {
39
44
  event: 'Store Palette Changed';
40
45
  before: Record<string, unknown>;
@@ -323,7 +328,7 @@ declare global {
323
328
  event: 'Impersonation UI Ended';
324
329
  target_store_id: string;
325
330
  }
326
- type UserActivityEvent = UserLoggedInEvent | UserLoggedOutEvent | UserPasswordChangedEvent | UserSuspendedEvent | TwoFactorEnrolledEvent | TwoFactorDisabledEvent | TwoFactorResetEvent | StorePaletteChangedEvent | StoreSettingsUpdatedEvent | PlanChangedEvent | InvoiceCreatedEvent | OrderCreatedEvent | OrderCancelledEvent | ProductPriceChangedEvent | CustomerCreatedEvent | CustomerEditedEvent | CashDrawerOpenedEvent | CashDrawerClosedEvent | TenantImpersonatedEvent | SecretRotatedEvent | UserCreatedEvent | UserUpdatedEvent | ProductCreatedEvent | ProductUpdatedEvent | StockIncomeCreatedEvent | CategoryCreatedEvent | CategoryUpdatedEvent | BrandCreatedEvent | BrandUpdatedEvent | SupplierCreatedEvent | SupplierUpdatedEvent | SupplierInvoiceCreatedEvent | SupplierAccountCreatedEvent | SupplierAccountUpdatedEvent | AccountCreatedEvent | AccountDeletedEvent | BasketUpdatedEvent | BasketDeletedEvent | CashDrawerMovementEvent | PaymentCreatedEvent | PaymentLinkedEvent | PaymentUnlinkedEvent | PaymentLinkageUpdatedEvent | NotificationReadEvent | LogDeletedEvent | PlanCreatedEvent | StoreMaintenanceToggledEvent | PlatformMaintenanceToggledEvent | TenantCreatedEvent | LiteralUpdatedEvent | SupportTicketCreatedEvent | SupportTicketUpdatedEvent | AuditTrailViewedEvent | ReportViewedEvent | CustomerPiiViewedEvent | CashDrawerUiOpenedEvent | CashDrawerUiClosedEvent | ExportInitiatedEvent | ImpersonationUiStartedEvent | ImpersonationUiEndedEvent;
331
+ type UserActivityEvent = UserLoggedInEvent | UserLoggedOutEvent | UserPasswordChangedEvent | UserSuspendedEvent | TwoFactorEnrolledEvent | TwoFactorDisabledEvent | TwoFactorResetEvent | TwoFactorRecoveryCodesGeneratedEvent | StorePaletteChangedEvent | StoreSettingsUpdatedEvent | PlanChangedEvent | InvoiceCreatedEvent | OrderCreatedEvent | OrderCancelledEvent | ProductPriceChangedEvent | CustomerCreatedEvent | CustomerEditedEvent | CashDrawerOpenedEvent | CashDrawerClosedEvent | TenantImpersonatedEvent | SecretRotatedEvent | UserCreatedEvent | UserUpdatedEvent | ProductCreatedEvent | ProductUpdatedEvent | StockIncomeCreatedEvent | CategoryCreatedEvent | CategoryUpdatedEvent | BrandCreatedEvent | BrandUpdatedEvent | SupplierCreatedEvent | SupplierUpdatedEvent | SupplierInvoiceCreatedEvent | SupplierAccountCreatedEvent | SupplierAccountUpdatedEvent | AccountCreatedEvent | AccountDeletedEvent | BasketUpdatedEvent | BasketDeletedEvent | CashDrawerMovementEvent | PaymentCreatedEvent | PaymentLinkedEvent | PaymentUnlinkedEvent | PaymentLinkageUpdatedEvent | NotificationReadEvent | LogDeletedEvent | PlanCreatedEvent | StoreMaintenanceToggledEvent | PlatformMaintenanceToggledEvent | TenantCreatedEvent | LiteralUpdatedEvent | SupportTicketCreatedEvent | SupportTicketUpdatedEvent | AuditTrailViewedEvent | ReportViewedEvent | CustomerPiiViewedEvent | CashDrawerUiOpenedEvent | CashDrawerUiClosedEvent | ExportInitiatedEvent | ImpersonationUiStartedEvent | ImpersonationUiEndedEvent;
327
332
  }
328
333
  /**
329
334
  * Canonical whitelist of UI-only `UserActivityEvent` variant names — the 8
@@ -14,12 +14,13 @@
14
14
  // - Erasure: append-only / anti-erasure per Ley 25.326 audit-trail exemption
15
15
  // - Ingest: synchronous REST-handler helper (WS ingest explicitly disallowed)
16
16
  //
17
- // 60 variants:
17
+ // 61 variants:
18
18
  // - 1.6.11 (Phase 1, 17 variants) — MVP wire-ins covering the hot paths
19
19
  // - 1.6.12 (Phase 2, +32 variants) — full mutating admin-handler coverage
20
20
  // - 1.6.13 (Phase 3, +8 UI-only variants) — FE companion (app#1642, api#1247)
21
21
  // - 1.6.18 (+2 variants) — TOTP 2FA enroll/disable lifecycle (types#68, api#636)
22
22
  // - 1.6.20 (+1 variant) — operator 2FA reset, target_user_id (api#1335)
23
+ // - 1.6.21 (+1 variant) — TOTP recovery codes generated (api#1336); method += 'recovery'
23
24
  /**
24
25
  * Canonical whitelist of UI-only `UserActivityEvent` variant names — the 8
25
26
  * Phase 3 verbs shipped in 1.6.13 (types#74). Imported by the api side
@@ -88,5 +88,87 @@ declare global {
88
88
  pricing_model: 'CBP' | string;
89
89
  category: 'user_initiated' | string;
90
90
  }
91
+ /** Per-tenant WhatsApp Business connection + plan tier. */
92
+ interface WhatsAppConfig {
93
+ wabaId: string;
94
+ phoneNumberId: string;
95
+ /** Meta access token — encrypted at rest. */
96
+ accessToken: string;
97
+ verifiedName: string;
98
+ qualityRating: 'GREEN' | 'YELLOW' | 'RED';
99
+ status: 'connected' | 'disconnected' | 'suspended';
100
+ tier: 'free' | 'pro' | 'enterprise';
101
+ /** ISO timestamp. */
102
+ connectedAt: string;
103
+ /** ISO timestamp. */
104
+ disconnectedAt?: string;
105
+ }
106
+ /** A customer conversation thread. */
107
+ interface WhatsAppConversation {
108
+ conversationId: string;
109
+ storeId: string;
110
+ customerId: string;
111
+ customerPhone: string;
112
+ customerName: string;
113
+ lastMessage: WhatsAppChatMessage;
114
+ unreadCount: number;
115
+ status: 'active' | 'resolved';
116
+ /** userId of the assigned agent (Enterprise tier). */
117
+ assignedTo?: string;
118
+ /** ISO timestamp. */
119
+ createdAt: string;
120
+ /** ISO timestamp. */
121
+ updatedAt: string;
122
+ }
123
+ /** A single message within a conversation. */
124
+ interface WhatsAppChatMessage {
125
+ messageId: string;
126
+ conversationId: string;
127
+ direction: 'inbound' | 'outbound';
128
+ type: 'text' | 'template' | 'image' | 'document' | 'interactive';
129
+ content: string;
130
+ templateName?: string;
131
+ mediaUrl?: string;
132
+ status: 'sent' | 'delivered' | 'read' | 'failed';
133
+ /** ISO timestamp. */
134
+ timestamp: string;
135
+ /** userId for outbound messages. */
136
+ sentBy?: string;
137
+ }
138
+ /** Per-tenant, per-period message usage for metered billing (Model C). */
139
+ interface WhatsAppUsage {
140
+ storeId: string;
141
+ /** Billing period, YYYY-MM. */
142
+ billingPeriod: string;
143
+ messageCount: number;
144
+ allowance: number;
145
+ overage: number;
146
+ tier: 'free' | 'pro' | 'enterprise';
147
+ }
148
+ /** A reusable message template registered with Meta. */
149
+ interface WhatsAppTemplate {
150
+ templateId: string;
151
+ name: string;
152
+ category: 'marketing' | 'utility' | 'authentication';
153
+ language: string;
154
+ status: 'APPROVED' | 'PENDING' | 'REJECTED';
155
+ components: WhatsAppTemplateComponent[];
156
+ /** ISO timestamp. */
157
+ createdAt: string;
158
+ /** ISO timestamp. */
159
+ updatedAt: string;
160
+ }
161
+ interface WhatsAppTemplateComponent {
162
+ type: 'HEADER' | 'BODY' | 'FOOTER' | 'BUTTONS';
163
+ format?: 'TEXT' | 'IMAGE' | 'VIDEO' | 'DOCUMENT';
164
+ text?: string;
165
+ buttons?: WhatsAppTemplateButton[];
166
+ }
167
+ interface WhatsAppTemplateButton {
168
+ type: 'QUICK_REPLY' | 'URL' | 'PHONE_NUMBER';
169
+ text: string;
170
+ url?: string;
171
+ phoneNumber?: string;
172
+ }
91
173
  }
92
174
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sinfactura-types",
3
- "version": "1.6.20",
3
+ "version": "1.6.22",
4
4
  "main": "dist/index.js",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",