sinfactura-types 1.9.0 → 1.10.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.
@@ -89,6 +89,12 @@ exports.SOCKET_ACTIONS = [
89
89
  'print-product',
90
90
  'print-tag',
91
91
  'print_job_failed',
92
+ // BE → agent: re-send your COMPLETE printer set (api#2006). Carries only
93
+ // `storeId`; the agent already knows what to report. Exists because
94
+ // `register_printers` fires just on connect and on local printer change, so
95
+ // an agent that connected before the registry shipped stays invisible to it
96
+ // until it happens to reconnect — days, for a machine that is never restarted.
97
+ 'request_printers',
92
98
  // Operations / operator surfaces.
93
99
  'logs',
94
100
  'maintenance',
@@ -109,15 +115,15 @@ exports.isSocketAction = isSocketAction;
109
115
  * The first four mirror the zod discriminated union in
110
116
  * `api/stacks/wss/lambdas/socket/default.ts` and are live today.
111
117
  *
112
- * ⚠️ `register_printers` is published AHEAD of the backend (api#2005 /
113
- * api#2006 / sinfactura/print#156) so the agent, api, and app lanes can build
114
- * against one `.d.ts` instead of discovering a mismatch at integration. The
115
- * api's union does **not** accept it yet — sending it before api#2006 ships
116
- * fails validation. Check the api lane before wiring it in an agent build.
118
+ * `register_printers` is **live**: api#2006 shipped its handler and the `$default`
119
+ * union, deployed and verified against a real agent on 2026-08-01. It was
120
+ * published ahead of that backend so the agent, api and app lanes could build
121
+ * against one `.d.ts` — which is exactly how api#2017 caught the frame being
122
+ * declared nested while every sibling is flat, before an agent shipped against it.
117
123
  */
118
124
  exports.CLIENT_SOCKET_ACTIONS = ['auth', 'logs', 'heartbeat', 'ack', 'register_printers'];
119
125
  /** Client→server actions the backend accepts **today**. */
120
- exports.LIVE_CLIENT_SOCKET_ACTIONS = ['auth', 'logs', 'heartbeat', 'ack'];
126
+ exports.LIVE_CLIENT_SOCKET_ACTIONS = ['auth', 'logs', 'heartbeat', 'ack', 'register_printers'];
121
127
  /* -------------------------------------------------------------------------- */
122
128
  /* Control frames */
123
129
  /* -------------------------------------------------------------------------- */
package/dist/print.d.ts CHANGED
@@ -171,7 +171,10 @@ declare global {
171
171
  */
172
172
  type PrintPrinterReport = Omit<PrintPrinter, 'agentId' | 'active' | 'reportedAt' | 'online'>;
173
173
  /**
174
- * agent → BE WSS payload: `{ action: 'register_printers', data: RegisterPrintersData }`.
174
+ * payload of the agent → BE `register_printers` WSS frame. ⚠️ That frame is
175
+ * **FLAT** — `{ action, printers }`, NOT `{ action, data }` (api#2017); this type
176
+ * describes the fields, not a nested envelope. `agentId` here is advisory: the api
177
+ * derives it from the authenticated SOCKET row and is not declared on the frame.
175
178
  */
176
179
  interface RegisterPrintersData {
177
180
  agentId: string;
package/dist/report.d.ts CHANGED
@@ -32,5 +32,120 @@ declare global {
32
32
  /** `cost - returnCost`. */
33
33
  netCost: number;
34
34
  }
35
+ /**
36
+ * One FAC/NC/net bucket of the ventas IVA summary (api#2011).
37
+ *
38
+ * ⚠️ Every amount is a POSITIVE magnitude, including `credit`. The netting is
39
+ * expressed by the `net` bucket, never by a sign on `credit` — same
40
+ * convention the fiscal files use, where a credit-note row also stays
41
+ * positive and the `CbteTipo` carries the sign semantics.
42
+ */
43
+ interface ReportInvoicesAmounts {
44
+ /** Voucher count in this bucket. */
45
+ quantity: number;
46
+ /** Neto gravado summed over every declared alícuota. */
47
+ neto: number;
48
+ /** Débito fiscal (IVA) summed over every declared alícuota. */
49
+ iva: number;
50
+ /** `ImpTotal` sum. */
51
+ total: number;
52
+ }
53
+ /**
54
+ * One day of the `GET /reports?mode=invoices&date=YYYYMM` ventas summary
55
+ * (api#2011 / types#113).
56
+ *
57
+ * Covers only AUTHORIZED (deliverable) vouchers — `pending_cae` and
58
+ * `rejected` are excluded upstream, and legacy rows with no `fiscalStatus`
59
+ * count as authorized.
60
+ */
61
+ interface ReportInvoicesResume {
62
+ /**
63
+ * `YYYYMMDD` as a NUMBER.
64
+ *
65
+ * ⚠️ Was typed `string` in the app's local copy of this shape while the
66
+ * API has always returned `Invoice.dated`, a number. Canonicalizing here
67
+ * fixes that drift — the same class of bug as `ReportSales.date`.
68
+ */
69
+ date: number;
70
+ /** Count of ALL deliverable vouchers this day, credit notes included. */
71
+ quantity: number;
72
+ /**
73
+ * Legacy roll-up columns. These sum EVERY deliverable voucher with a
74
+ * POSITIVE sign — credit notes included — so `total` is a mixture of
75
+ * debits and credits rather than a meaningful sales figure. Retained
76
+ * unchanged for wire compatibility; prefer `gross`/`credit`/`net` below.
77
+ *
78
+ * `neto10`/`neto21`/`iva10`/`iva21` only ever covered AFIP `Iva[].Id` 4
79
+ * (10,5 %) and 5 (21 %); `neto`/`iva` are the all-alícuota roll-ups added
80
+ * by api#1961.
81
+ */
82
+ neto10: number;
83
+ neto21: number;
84
+ iva10: number;
85
+ iva21: number;
86
+ neto: number;
87
+ iva: number;
88
+ total: number;
89
+ /** Non-credit vouchers — facturas and notas de débito. */
90
+ gross: ReportInvoicesAmounts;
91
+ /**
92
+ * Notas de crédito only, as positive magnitudes. Classified via the
93
+ * canonical `NC_CBTE_TIPOS` family, NOT a hardcoded `[3, 8, 13]`.
94
+ *
95
+ * ⚠️ Notas de DÉBITO are deliberately NOT here — a débito increases what
96
+ * is owed, so it belongs in `gross`. Netting both would move the total in
97
+ * the wrong direction.
98
+ */
99
+ credit: ReportInvoicesAmounts;
100
+ /** `gross - credit`, field by field. The figure an operator should read. */
101
+ net: ReportInvoicesAmounts;
102
+ }
103
+ /**
104
+ * One voucher row of the ventas summary's spreadsheet export.
105
+ *
106
+ * ⚠️ Mixed string/number by design — the padded fiscal columns are strings
107
+ * while the amounts are numbers. The app's local copy typed this
108
+ * `Record<string, string>[]`, which was wrong for five of the ten fields.
109
+ */
110
+ interface ReportInvoicesVoucherRow {
111
+ FECHA: string;
112
+ CBTE_TIPO: string;
113
+ PTO_VTA: string;
114
+ CBTE_NUMERO: number;
115
+ RAZON_SOCIAL: string;
116
+ CUIT: string;
117
+ NETO: number;
118
+ NETO10: number;
119
+ NETO21: number;
120
+ TOTAL: number;
121
+ }
122
+ /**
123
+ * `GET /reports?mode=invoices&date=YYYYMM` response payload.
124
+ *
125
+ * Carries BOTH the operator-facing summary (`resume`, `period`) and the ARCA
126
+ * REGINFO_CV_VENTAS flat files (`customers`, `reg_alicuotas`, `reg_cbte`).
127
+ *
128
+ * ⚠️ The two are produced from the same voucher set but must never share sign
129
+ * semantics: the summary nets credit notes, the flat files keep every voucher
130
+ * a positive magnitude carrying its own `CbteTipo`. A sign leak into the
131
+ * fixed-width records corrupts a filing.
132
+ */
133
+ interface ReportInvoices {
134
+ /** Per-day rows, ascending by `date`. */
135
+ resume: ReportInvoicesResume[];
136
+ /** Same FAC/NC/net split aggregated over the whole selected period (api#2011). */
137
+ period: {
138
+ gross: ReportInvoicesAmounts;
139
+ credit: ReportInvoicesAmounts;
140
+ net: ReportInvoicesAmounts;
141
+ };
142
+ invoices: ReportInvoicesVoucherRow[];
143
+ /** REGINFO_CV_VENTAS fixed-width padrón de clientes. */
144
+ customers: string;
145
+ /** REGINFO_CV_VENTAS_ALICUOTAS.TXT — one record per declared alícuota. */
146
+ reg_alicuotas: string;
147
+ /** REGINFO_CV_VENTAS_CBTE.TXT — one record per voucher. */
148
+ reg_cbte: string;
149
+ }
35
150
  }
36
151
  export {};
package/dist/socket.d.ts CHANGED
@@ -34,7 +34,7 @@
34
34
  * (`wsPostStore`). A client must ignore actions it does not own rather than
35
35
  * assume it receives all of them.
36
36
  */
37
- export declare const SOCKET_ACTIONS: readonly ["account", "baskets", "brands", "cash", "categories", "customers", "globals", "invoices", "literals", "orders", "products", "shifts", "stores", "suppliers", "supplier-invoice", "support", "surveys", "users", "favorites", "account-delete", "baskets-delete", "log-delete", "notifications", "support-message", "whatsapp-message", "payment_received", "payment_linked", "payment_unlinked", "mercadopago", "mercadopago_dynamic_qr_created", "mercadopago_static_qr_created", "mp_hook_log_appended", "mp_ipn_log_appended", "stripe", "subscription", "caea", "print", "print-order", "print-invoice", "print-product", "print-tag", "print_job_failed", "logs", "maintenance", "currency_auto_updated", "drain_progress", "integration_event_appended", "userActivityRecorded"];
37
+ export declare const SOCKET_ACTIONS: readonly ["account", "baskets", "brands", "cash", "categories", "customers", "globals", "invoices", "literals", "orders", "products", "shifts", "stores", "suppliers", "supplier-invoice", "support", "surveys", "users", "favorites", "account-delete", "baskets-delete", "log-delete", "notifications", "support-message", "whatsapp-message", "payment_received", "payment_linked", "payment_unlinked", "mercadopago", "mercadopago_dynamic_qr_created", "mercadopago_static_qr_created", "mp_hook_log_appended", "mp_ipn_log_appended", "stripe", "subscription", "caea", "print", "print-order", "print-invoice", "print-product", "print-tag", "print_job_failed", "request_printers", "logs", "maintenance", "currency_auto_updated", "drain_progress", "integration_event_appended", "userActivityRecorded"];
38
38
  /** Union of every server→client data-frame action. */
39
39
  export type SocketAction = (typeof SOCKET_ACTIONS)[number];
40
40
  /** Runtime guard — narrows an untrusted string to a known action. */
@@ -56,17 +56,17 @@ export interface SocketMessage<T = unknown> {
56
56
  * The first four mirror the zod discriminated union in
57
57
  * `api/stacks/wss/lambdas/socket/default.ts` and are live today.
58
58
  *
59
- * ⚠️ `register_printers` is published AHEAD of the backend (api#2005 /
60
- * api#2006 / sinfactura/print#156) so the agent, api, and app lanes can build
61
- * against one `.d.ts` instead of discovering a mismatch at integration. The
62
- * api's union does **not** accept it yet — sending it before api#2006 ships
63
- * fails validation. Check the api lane before wiring it in an agent build.
59
+ * `register_printers` is **live**: api#2006 shipped its handler and the `$default`
60
+ * union, deployed and verified against a real agent on 2026-08-01. It was
61
+ * published ahead of that backend so the agent, api and app lanes could build
62
+ * against one `.d.ts` — which is exactly how api#2017 caught the frame being
63
+ * declared nested while every sibling is flat, before an agent shipped against it.
64
64
  */
65
65
  export declare const CLIENT_SOCKET_ACTIONS: readonly ["auth", "logs", "heartbeat", "ack", "register_printers"];
66
66
  /** Union of every client→server action. */
67
67
  export type ClientSocketAction = (typeof CLIENT_SOCKET_ACTIONS)[number];
68
68
  /** Client→server actions the backend accepts **today**. */
69
- export declare const LIVE_CLIENT_SOCKET_ACTIONS: readonly ["auth", "logs", "heartbeat", "ack"];
69
+ export declare const LIVE_CLIENT_SOCKET_ACTIONS: readonly ["auth", "logs", "heartbeat", "ack", "register_printers"];
70
70
  /** Authenticate the connection. Must be the first frame; see `AuthAckFrame`. */
71
71
  export interface SocketAuthMessage {
72
72
  action: 'auth';
@@ -99,13 +99,30 @@ export interface SocketAckMessage {
99
99
  [key: string]: unknown;
100
100
  }
101
101
  /**
102
- * Agent → BE printer registry report (api#2005). `data` is the COMPLETE current
103
- * printer set for the agent, not a delta. Not accepted by the api until
104
- * api#2006 — see `CLIENT_SOCKET_ACTIONS`.
102
+ * Agent → BE printer registry report (api#2006). `printers` is the agent's
103
+ * COMPLETE current set, never a delta — the BE marks absent printers offline
104
+ * rather than deleting them, because deleting would orphan any `PrintRule`
105
+ * pointing at one.
106
+ *
107
+ * **FLAT, like every other client→server frame** (api#2017). 1.9.0–1.9.1
108
+ * declared this nested (`{ action, data }`) — the only nested client action —
109
+ * and that was wrong: the agent's sender builds `{ action, ...data }` by design,
110
+ * reserving nested payloads for server→client frames, and the api destructures
111
+ * `const { action, ...data }`. A union entry written to match the nested
112
+ * declaration would have rejected every real report with `400 Invalid message`
113
+ * and left the registry silently empty, presenting as an agent bug.
114
+ *
115
+ * `agentId` is deliberately **not declared**. The api derives it from the
116
+ * authenticated SOCKET row, because trusting a frame-supplied value would let
117
+ * one agent register printers under another's id. The open index signature still
118
+ * permits sending it, and the api treats it as advisory — falling back to it only
119
+ * when the connection has no `agentId` yet, since a report can arrive before the
120
+ * agent's first heartbeat.
105
121
  */
106
122
  export interface SocketRegisterPrintersMessage {
107
123
  action: 'register_printers';
108
- data: RegisterPrintersData;
124
+ printers: PrintPrinterReport[];
125
+ [key: string]: unknown;
109
126
  }
110
127
  /** Any client→server JSON frame. */
111
128
  export type ClientSocketMessage = SocketAuthMessage | SocketLogsMessage | SocketHeartbeatMessage | SocketAckMessage | SocketRegisterPrintersMessage;
package/dist/socket.js CHANGED
@@ -86,6 +86,12 @@ export const SOCKET_ACTIONS = [
86
86
  'print-product',
87
87
  'print-tag',
88
88
  'print_job_failed',
89
+ // BE → agent: re-send your COMPLETE printer set (api#2006). Carries only
90
+ // `storeId`; the agent already knows what to report. Exists because
91
+ // `register_printers` fires just on connect and on local printer change, so
92
+ // an agent that connected before the registry shipped stays invisible to it
93
+ // until it happens to reconnect — days, for a machine that is never restarted.
94
+ 'request_printers',
89
95
  // Operations / operator surfaces.
90
96
  'logs',
91
97
  'maintenance',
@@ -105,15 +111,15 @@ export const isSocketAction = (value) => typeof value === 'string' && SOCKET_ACT
105
111
  * The first four mirror the zod discriminated union in
106
112
  * `api/stacks/wss/lambdas/socket/default.ts` and are live today.
107
113
  *
108
- * ⚠️ `register_printers` is published AHEAD of the backend (api#2005 /
109
- * api#2006 / sinfactura/print#156) so the agent, api, and app lanes can build
110
- * against one `.d.ts` instead of discovering a mismatch at integration. The
111
- * api's union does **not** accept it yet — sending it before api#2006 ships
112
- * fails validation. Check the api lane before wiring it in an agent build.
114
+ * `register_printers` is **live**: api#2006 shipped its handler and the `$default`
115
+ * union, deployed and verified against a real agent on 2026-08-01. It was
116
+ * published ahead of that backend so the agent, api and app lanes could build
117
+ * against one `.d.ts` — which is exactly how api#2017 caught the frame being
118
+ * declared nested while every sibling is flat, before an agent shipped against it.
113
119
  */
114
120
  export const CLIENT_SOCKET_ACTIONS = ['auth', 'logs', 'heartbeat', 'ack', 'register_printers'];
115
121
  /** Client→server actions the backend accepts **today**. */
116
- export const LIVE_CLIENT_SOCKET_ACTIONS = ['auth', 'logs', 'heartbeat', 'ack'];
122
+ export const LIVE_CLIENT_SOCKET_ACTIONS = ['auth', 'logs', 'heartbeat', 'ack', 'register_printers'];
117
123
  /* -------------------------------------------------------------------------- */
118
124
  /* Control frames */
119
125
  /* -------------------------------------------------------------------------- */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sinfactura-types",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "main": "dist/index.js",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",