sinfactura-types 1.10.237 → 1.10.239

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.
@@ -222,5 +222,70 @@ declare global {
222
222
  createdAt: number;
223
223
  updatedAt?: number;
224
224
  }
225
+ /** One datapoint of the campaign-engagement time series. `t` is epoch MILLISECONDS. */
226
+ interface CampaignEmailMetricPoint {
227
+ t: number;
228
+ v: number;
229
+ }
230
+ /**
231
+ * `GET /campaigns?mode=metrics` — the store's MARKETING email engagement,
232
+ * read from the CloudWatch event destination of the marketing SES
233
+ * Configuration Set.
234
+ *
235
+ * ⚠️ **Marketing mail only, and that is the point.** The figures come from
236
+ * the `sinfactura-email-marketing{-dev}` Configuration Set, which only a
237
+ * `kind: 'marketing'` send names. Password resets, OTP codes and order
238
+ * confirmations are on a different set with a different CloudWatch dimension
239
+ * set and cannot appear here — a transactional email is opened at a far
240
+ * higher rate than a campaign, so commingling them would produce an "open
241
+ * rate" that moves with transactional volume.
242
+ *
243
+ * ⚠️ **There is no `sent` figure, and its absence is deliberate.** The
244
+ * marketing Configuration Set does not publish the `SEND` event type, so no
245
+ * per-store send count exists in CloudWatch at all. `delivered` is the only
246
+ * available denominator. For attempted-send counts use `Campaign`'s own
247
+ * `queuedCount`/`sentCount` counters, which measure a different thing (what
248
+ * the worker handed to the transport, not what SES delivered).
249
+ */
250
+ interface CampaignEmailMetricsResponse {
251
+ storeId: string;
252
+ window: CampaignEmailMetricWindow;
253
+ /**
254
+ * Sums over the window.
255
+ *
256
+ * ⚠️ `opened` is TOTAL opens, not unique openers. SES emits one event per
257
+ * open, so one recipient opening five times counts five — and image
258
+ * caching plus privacy-protecting mail providers skew it in both
259
+ * directions. Read it as a floor with noise on top, never as a headcount.
260
+ * The per-message `EMAILEVENT` rows answer the unique-per-message question
261
+ * instead.
262
+ */
263
+ totals: {
264
+ delivered: number;
265
+ opened: number;
266
+ bounced: number;
267
+ complained: number;
268
+ rejected: number;
269
+ };
270
+ /**
271
+ * `opened / delivered`, ABSENT when nothing was delivered in the window.
272
+ *
273
+ * ⚠️ Absence is not zero. A store that sent no campaign and a store whose
274
+ * campaign nobody opened must not render identically — a synthesised `0`
275
+ * reads as "the campaign flopped" when the truth is "there was no
276
+ * campaign". ⚠️ It can exceed `1`, because the numerator counts repeat
277
+ * opens and the denominator counts messages.
278
+ */
279
+ openRate?: number;
280
+ /** Per-period series over the same window, ascending by `t`. */
281
+ series: {
282
+ delivered: CampaignEmailMetricPoint[];
283
+ opened: CampaignEmailMetricPoint[];
284
+ };
285
+ /** Unix MILLISECONDS the figures were read at. */
286
+ generatedAt: number;
287
+ }
288
+ /** Look-back window for {@link CampaignEmailMetricsResponse}. */
289
+ type CampaignEmailMetricWindow = '24h' | '7d' | '30d';
225
290
  }
226
291
  export {};
package/dist/order.d.ts CHANGED
@@ -872,6 +872,28 @@ declare global {
872
872
  source: 'mp' | 'stripe' | 'mp_movement';
873
873
  total: number;
874
874
  linkedAt: number;
875
+ /**
876
+ * The denomination `total` is expressed in, as the provider stated it —
877
+ * an ISO code (`'USD'`) or a platform catalogId (`'usd-oficial'`), both
878
+ * accepted by the FX resolver.
879
+ *
880
+ * ⚠️ **ABSENT means "the order's own currency", and that is a
881
+ * back-catalogue reading, not a default.** Every entry written before
882
+ * this field existed carries no denomination at all and there is no
883
+ * backfill, so a reader summing the map has to assume parity for those —
884
+ * which is exactly the assumption this field exists to stop making
885
+ * going forward. A writer that knows the provider's currency MUST stamp
886
+ * it, even when it equals the order's: an entry that omits it is
887
+ * indistinguishable from a legacy row.
888
+ *
889
+ * ⚠️ Every entry in this map is SETTLED by construction — each writer
890
+ * only creates one once its provider says the money moved (Stripe
891
+ * `payment_intent.succeeded` / `charge.succeeded`, MercadoPago
892
+ * `status === 'approved'`, a manual link against an already-recorded
893
+ * PAYMENT row). There is deliberately no per-entry status: a pending
894
+ * provider notification never reaches this map at all.
895
+ */
896
+ currency?: string;
875
897
  }
876
898
  /**
877
899
  * The body of `POST /orders` on the CREATE / UPDATE path — the one carrying no
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sinfactura-types",
3
- "version": "1.10.237",
3
+ "version": "1.10.239",
4
4
  "description": "Shared wire and entity contracts for the SINFACTURA platform.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",