@vitrina/api 15.19.0 → 15.20.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 (3) hide show
  1. package/dist/index.d.cts +2453 -140
  2. package/dist/index.d.ts +2453 -140
  3. package/package.json +1 -1
package/dist/index.d.cts CHANGED
@@ -76078,6 +76078,7 @@ interface paths {
76078
76078
  query?: {
76079
76079
  kind?: "purchase" | "sale" | "honorario" | "manual_expense" | "tax";
76080
76080
  source?: "sii" | "vitrina" | "manual" | "chipax";
76081
+ origin?: "ads";
76081
76082
  period?: string;
76082
76083
  from?: string;
76083
76084
  to?: string;
@@ -82077,7 +82078,7 @@ interface paths {
82077
82078
  get: {
82078
82079
  parameters: {
82079
82080
  query?: {
82080
- kind?: "reconcile" | "transfer" | "classify" | "missing_document" | "unknown";
82081
+ kind?: "reconcile" | "transfer" | "classify" | "missing_document" | "unknown" | "ads_charge";
82081
82082
  limit?: number;
82082
82083
  offset?: number | null;
82083
82084
  };
@@ -83610,7 +83611,11 @@ interface paths {
83610
83611
  * "unreviewed_count": 4,
83611
83612
  * "unclassified_count": 0,
83612
83613
  * "unmatched_count": 0,
83613
- * "unmatched_pending_clp": 0
83614
+ * "unmatched_movements_count": 0,
83615
+ * "unmatched_documents_count": 0,
83616
+ * "unmatched_pending_clp": 0,
83617
+ * "unmatched_movements_pending_clp": 0,
83618
+ * "unmatched_documents_pending_clp": 0
83614
83619
  * },
83615
83620
  * "close": {
83616
83621
  * "unreviewed_count": 4,
@@ -83656,6 +83661,10 @@ interface paths {
83656
83661
  * "unmatched_movements": {
83657
83662
  * "count": 0,
83658
83663
  * "pending_clp": 0
83664
+ * },
83665
+ * "unmatched_documents": {
83666
+ * "count": 0,
83667
+ * "pending_clp": 0
83659
83668
  * }
83660
83669
  * }
83661
83670
  * },
@@ -83803,7 +83812,11 @@ interface paths {
83803
83812
  * "unreviewed_count": 4,
83804
83813
  * "unclassified_count": 0,
83805
83814
  * "unmatched_count": 0,
83806
- * "unmatched_pending_clp": 0
83815
+ * "unmatched_movements_count": 0,
83816
+ * "unmatched_documents_count": 0,
83817
+ * "unmatched_pending_clp": 0,
83818
+ * "unmatched_movements_pending_clp": 0,
83819
+ * "unmatched_documents_pending_clp": 0
83807
83820
  * },
83808
83821
  * "close": {
83809
83822
  * "unreviewed_count": 4,
@@ -83849,6 +83862,10 @@ interface paths {
83849
83862
  * "unmatched_movements": {
83850
83863
  * "count": 0,
83851
83864
  * "pending_clp": 0
83865
+ * },
83866
+ * "unmatched_documents": {
83867
+ * "count": 0,
83868
+ * "pending_clp": 0
83852
83869
  * }
83853
83870
  * }
83854
83871
  * },
@@ -84087,7 +84104,7 @@ interface paths {
84087
84104
  patch?: never;
84088
84105
  trace?: never;
84089
84106
  };
84090
- "/finanzas/chipax": {
84107
+ "/finanzas/chipax/shadow": {
84091
84108
  parameters: {
84092
84109
  query?: never;
84093
84110
  header?: never;
@@ -84095,8 +84112,8 @@ interface paths {
84095
84112
  cookie?: never;
84096
84113
  };
84097
84114
  /**
84098
- * Importar desde Chipax: connection and runs
84099
- * @description Whether the workspace stored its Chipax API credentials (only a masked App ID hint, never the secret), the run in progress and the last finished one. Vitrina only READS Chipax: it logs in and sends GET requests; it never creates, edits or deletes anything in the Chipax account. Requires the `finanzas` add-on — without it every Finanzas operation answers `402 ENTITLEMENT_NOT_ACTIVE` (`details.required = ["finanzas"]`). Requires `finanzas:read`.
84115
+ * Mes en sombra: the months read from Chipax
84116
+ * @description Each month with a Chipax read, newest first: its newest read (any status) and when it was last read successfully. Requires the `finanzas` add-on — without it every Finanzas operation answers `402 ENTITLEMENT_NOT_ACTIVE` (`details.required = ["finanzas"]`). Requires `finanzas:read` and `finanzas_reports:read` (the Contador seat, owners and admins).
84100
84117
  */
84101
84118
  get: {
84102
84119
  parameters: {
@@ -84107,7 +84124,7 @@ interface paths {
84107
84124
  };
84108
84125
  requestBody?: never;
84109
84126
  responses: {
84110
- /** @description Connection and runs */
84127
+ /** @description Months */
84111
84128
  200: {
84112
84129
  headers: {
84113
84130
  [name: string]: unknown;
@@ -84115,30 +84132,51 @@ interface paths {
84115
84132
  content: {
84116
84133
  /**
84117
84134
  * @example {
84118
- * "data": {
84119
- * "connected": true,
84120
- * "app_id_preview": "a1b…9f2",
84121
- * "verified_at": "2026-10-30T21:58:40.000Z",
84122
- * "active_import": null,
84123
- * "last_import": {
84124
- * "id": "0190a3c2-5d1e-7b6a-9f20-4c1d2e3f5a16",
84125
- * "mode": "dry_run",
84126
- * "status": "done",
84127
- * "from": "2025-01-01",
84128
- * "to": "2026-10-30",
84129
- * "account_map": [],
84130
- * "requested_by": "0190a3c2-5d1e-7b6a-9f20-4c1d2e3f4f01",
84131
- * "error": null,
84132
- * "started_at": "2026-10-30T22:01:04.000Z",
84133
- * "finished_at": "2026-10-30T22:14:51.000Z",
84134
- * "created_at": "2026-10-30T22:01:02.000Z",
84135
- * "report": null
84135
+ * "data": [
84136
+ * {
84137
+ * "month": "2026-10",
84138
+ * "label": "octubre 2026",
84139
+ * "latest_read": {
84140
+ * "id": "01930000-0000-7000-8000-000000000017",
84141
+ * "month": "2026-10",
84142
+ * "status": "done",
84143
+ * "history_from": "2025-01-01",
84144
+ * "error": null,
84145
+ * "requested_by": "00000000-0000-4000-8000-000000000001",
84146
+ * "started_at": null,
84147
+ * "finished_at": null,
84148
+ * "created_at": "2026-11-02T12:00:00.000Z"
84149
+ * },
84150
+ * "read_at": "2026-11-02T12:04:10.000Z"
84136
84151
  * }
84137
- * }
84152
+ * ]
84138
84153
  * }
84139
84154
  */
84140
84155
  "application/json": {
84141
- data: components["schemas"]["FinanzasChipaxStatus"];
84156
+ data: {
84157
+ month: string;
84158
+ /** @description «septiembre 2026». */
84159
+ label: string;
84160
+ latest_read: {
84161
+ /** Format: uuid */
84162
+ id: string;
84163
+ month: string;
84164
+ /** @enum {string} */
84165
+ status: "queued" | "running" | "done" | "failed";
84166
+ /** @description Payables are compared among documents issued since this day (the earliest Chipax import, else a year before the month). */
84167
+ history_from: string;
84168
+ error: string | null;
84169
+ requested_by: string | null;
84170
+ /** @description ISO 8601 timestamp. */
84171
+ started_at: string | null;
84172
+ /** @description ISO 8601 timestamp. */
84173
+ finished_at: string | null;
84174
+ /** @description ISO 8601 timestamp. */
84175
+ created_at: string;
84176
+ };
84177
+ /** @description When the month was last read successfully. */
84178
+ read_at: string | null;
84179
+ }[];
84142
84180
  };
84143
84181
  };
84144
84182
  };
@@ -84199,37 +84237,161 @@ interface paths {
84199
84237
  };
84200
84238
  };
84201
84239
  put?: never;
84202
- post?: never;
84240
+ /**
84241
+ * Mes en sombra: read Chipax's side of a month
84242
+ * @description Queues a read of Chipax for the month (bank lines and balances, open payables, classified items, Resultado Operacional), over the documents issued since `history_from`. Takes minutes (Chipax's rate limit). One read at a time; refused while a Chipax import runs (409 `import_running`) or another read runs (409 `read_running`); 409 `not_connected` without Chipax credentials. Vitrina only READS Chipax: it logs in and sends GET requests; it never creates, edits or deletes anything in the Chipax account. Requires the `finanzas` add-on — without it every Finanzas operation answers `402 ENTITLEMENT_NOT_ACTIVE` (`details.required = ["finanzas"]`). Requires `finanzas_admin:write`.
84243
+ */
84244
+ post: {
84245
+ parameters: {
84246
+ query?: never;
84247
+ header?: {
84248
+ /** @description Replay-safe retries: resending the SAME key with the SAME body returns the original response (`X-Idempotent-Replay: 1`) instead of creating a second copy — safe to send whenever a response might not have arrived. The same key with a DIFFERENT body answers `409 IDEMPOTENCY_KEY_CONFLICT`; use a fresh key per operation. */
84249
+ "Idempotency-Key"?: string;
84250
+ };
84251
+ path?: never;
84252
+ cookie?: never;
84253
+ };
84254
+ requestBody?: {
84255
+ content: {
84256
+ /**
84257
+ * @example {
84258
+ * "month": "2026-10"
84259
+ * }
84260
+ */
84261
+ "application/json": {
84262
+ /** @description The shadow month (default: the month before the current one, America/Santiago). Up to the current month; a future month answers 400. */
84263
+ month?: string;
84264
+ };
84265
+ };
84266
+ };
84267
+ responses: {
84268
+ /** @description Read queued */
84269
+ 202: {
84270
+ headers: {
84271
+ [name: string]: unknown;
84272
+ };
84273
+ content: {
84274
+ /**
84275
+ * @example {
84276
+ * "data": {
84277
+ * "id": "01930000-0000-7000-8000-000000000017",
84278
+ * "month": "2026-10",
84279
+ * "status": "queued",
84280
+ * "history_from": "2025-01-01",
84281
+ * "error": null,
84282
+ * "requested_by": "00000000-0000-4000-8000-000000000001",
84283
+ * "started_at": null,
84284
+ * "finished_at": null,
84285
+ * "created_at": "2026-11-02T12:00:00.000Z"
84286
+ * }
84287
+ * }
84288
+ */
84289
+ "application/json": {
84290
+ data: {
84291
+ /** Format: uuid */
84292
+ id: string;
84293
+ month: string;
84294
+ /** @enum {string} */
84295
+ status: "queued" | "running" | "done" | "failed";
84296
+ /** @description Payables are compared among documents issued since this day (the earliest Chipax import, else a year before the month). */
84297
+ history_from: string;
84298
+ error: string | null;
84299
+ requested_by: string | null;
84300
+ /** @description ISO 8601 timestamp. */
84301
+ started_at: string | null;
84302
+ /** @description ISO 8601 timestamp. */
84303
+ finished_at: string | null;
84304
+ /** @description ISO 8601 timestamp. */
84305
+ created_at: string;
84306
+ };
84307
+ };
84308
+ };
84309
+ };
84310
+ /** @description Validation error */
84311
+ 400: {
84312
+ headers: {
84313
+ [name: string]: unknown;
84314
+ };
84315
+ content: {
84316
+ "application/json": components["schemas"]["Error"];
84317
+ };
84318
+ };
84319
+ /** @description Unauthorized */
84320
+ 401: {
84321
+ headers: {
84322
+ [name: string]: unknown;
84323
+ };
84324
+ content: {
84325
+ "application/json": components["schemas"]["Error"];
84326
+ };
84327
+ };
84328
+ /** @description Forbidden */
84329
+ 403: {
84330
+ headers: {
84331
+ [name: string]: unknown;
84332
+ };
84333
+ content: {
84334
+ "application/json": components["schemas"]["Error"];
84335
+ };
84336
+ };
84337
+ /** @description Not found */
84338
+ 404: {
84339
+ headers: {
84340
+ [name: string]: unknown;
84341
+ };
84342
+ content: {
84343
+ "application/json": components["schemas"]["Error"];
84344
+ };
84345
+ };
84346
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
84347
+ 409: {
84348
+ headers: {
84349
+ [name: string]: unknown;
84350
+ };
84351
+ content: {
84352
+ "application/json": components["schemas"]["Error"];
84353
+ };
84354
+ };
84355
+ /** @description Rate limited */
84356
+ 429: {
84357
+ headers: {
84358
+ [name: string]: unknown;
84359
+ };
84360
+ content: {
84361
+ "application/json": components["schemas"]["Error"];
84362
+ };
84363
+ };
84364
+ };
84365
+ };
84203
84366
  delete?: never;
84204
84367
  options?: never;
84205
84368
  head?: never;
84206
84369
  patch?: never;
84207
84370
  trace?: never;
84208
84371
  };
84209
- "/finanzas/chipax/credentials": {
84372
+ "/finanzas/chipax/shadow/{month}": {
84210
84373
  parameters: {
84211
84374
  query?: never;
84212
84375
  header?: never;
84213
84376
  path?: never;
84214
84377
  cookie?: never;
84215
84378
  };
84216
- get?: never;
84217
- put?: never;
84218
- post?: never;
84219
84379
  /**
84220
- * Importar desde Chipax: «Eliminar credenciales»
84221
- * @description Deletes the stored Chipax credentials. What was already imported stays. Idempotent. Requires the `finanzas` add-on — without it every Finanzas operation answers `402 ENTITLEMENT_NOT_ACTIVE` (`details.required = ["finanzas"]`). Requires `finanzas_admin:write`.
84380
+ * Mes en sombra: the diff against Chipax for a month
84381
+ * @description Balances (per bank account, at month end), payables (per Contraparte, open at month end) and costs (per costo / gasto account, NET as the Resultado counts) must match to the peso. Income is a bridge: Chipax counts it when cashed, Vitrina the documents issued in the month, so the gap is explained line by line. Vitrina's side is computed live; Chipax's side is the newest finished read. `clean` = all three match and the bridge is explained (the exit criterion). Each row's `key` drills down to its items. Before a finished read: `status` not_read / reading / failed and null dimensions. A caller without the patient register (the Contador) sees a patient as «Paciente A. P.» with no RUT and no glosa, on both sides; Chipax boletas carry neither RUT nor name. Requires the `finanzas` add-on — without it every Finanzas operation answers `402 ENTITLEMENT_NOT_ACTIVE` (`details.required = ["finanzas"]`). Requires `finanzas:read` and `finanzas_reports:read` (the Contador seat, owners and admins).
84222
84382
  */
84223
- delete: {
84383
+ get: {
84224
84384
  parameters: {
84225
84385
  query?: never;
84226
84386
  header?: never;
84227
- path?: never;
84387
+ path: {
84388
+ month: string;
84389
+ };
84228
84390
  cookie?: never;
84229
84391
  };
84230
84392
  requestBody?: never;
84231
84393
  responses: {
84232
- /** @description Deleted */
84394
+ /** @description The diff */
84233
84395
  200: {
84234
84396
  headers: {
84235
84397
  [name: string]: unknown;
@@ -84238,29 +84400,873 @@ interface paths {
84238
84400
  /**
84239
84401
  * @example {
84240
84402
  * "data": {
84241
- * "connected": false,
84242
- * "app_id_preview": null,
84243
- * "verified_at": null,
84244
- * "active_import": null,
84245
- * "last_import": {
84246
- * "id": "0190a3c2-5d1e-7b6a-9f20-4c1d2e3f5a16",
84247
- * "mode": "dry_run",
84403
+ * "month": "2026-10",
84404
+ * "label": "octubre 2026",
84405
+ * "status": "ready",
84406
+ * "read": {
84407
+ * "id": "01930000-0000-7000-8000-000000000017",
84408
+ * "month": "2026-10",
84248
84409
  * "status": "done",
84249
- * "from": "2025-01-01",
84250
- * "to": "2026-10-30",
84251
- * "account_map": [],
84252
- * "requested_by": "0190a3c2-5d1e-7b6a-9f20-4c1d2e3f4f01",
84410
+ * "history_from": "2025-01-01",
84253
84411
  * "error": null,
84254
- * "started_at": "2026-10-30T22:01:04.000Z",
84255
- * "finished_at": "2026-10-30T22:14:51.000Z",
84256
- * "created_at": "2026-10-30T22:01:02.000Z",
84257
- * "report": null
84412
+ * "requested_by": "00000000-0000-4000-8000-000000000001",
84413
+ * "started_at": null,
84414
+ * "finished_at": null,
84415
+ * "created_at": "2026-11-02T12:00:00.000Z"
84416
+ * },
84417
+ * "active_read": null,
84418
+ * "last_error": null,
84419
+ * "history_from": "2025-01-01",
84420
+ * "clean": false,
84421
+ * "warnings": [],
84422
+ * "balances": {
84423
+ * "matches": true,
84424
+ * "difference_count": 0,
84425
+ * "rows": [
84426
+ * {
84427
+ * "key": "bank:01930000-0000-7000-8000-0000000000b1",
84428
+ * "label": "Cuenta corriente",
84429
+ * "chipax_clp": 12480300,
84430
+ * "vitrina_clp": 12480300,
84431
+ * "difference_clp": 0,
84432
+ * "matches": true,
84433
+ * "item_count": 212,
84434
+ * "difference_count": 0,
84435
+ * "basis": "closing",
84436
+ * "vitrina_account": {
84437
+ * "id": "01930000-0000-7000-8000-0000000000b1",
84438
+ * "name": "Cuenta corriente",
84439
+ * "institution_name": "Banco de Chile",
84440
+ * "number_masked": "•••• 4321"
84441
+ * },
84442
+ * "chipax_account": {
84443
+ * "external_id": "881",
84444
+ * "name": "Cuenta corriente",
84445
+ * "bank": "Banco de Chile",
84446
+ * "number_masked": "•••• 4321"
84447
+ * },
84448
+ * "movements": {
84449
+ * "chipax_in_clp": 30100000,
84450
+ * "chipax_out_clp": 27620000,
84451
+ * "vitrina_in_clp": 30100000,
84452
+ * "vitrina_out_clp": 27620000
84453
+ * }
84454
+ * }
84455
+ * ]
84456
+ * },
84457
+ * "payables": {
84458
+ * "matches": false,
84459
+ * "chipax_clp": 4210000,
84460
+ * "vitrina_clp": 3800000,
84461
+ * "difference_clp": 410000,
84462
+ * "difference_count": 1,
84463
+ * "rows": [
84464
+ * {
84465
+ * "key": "p_0000000000000001",
84466
+ * "label": "Laboratorio Dental Andes Ltda",
84467
+ * "chipax_clp": 410000,
84468
+ * "vitrina_clp": null,
84469
+ * "difference_clp": 410000,
84470
+ * "matches": false,
84471
+ * "item_count": 1,
84472
+ * "difference_count": 1,
84473
+ * "rut": "76086428-5",
84474
+ * "contraparte_id": null
84475
+ * }
84476
+ * ]
84477
+ * },
84478
+ * "costs": {
84479
+ * "matches": true,
84480
+ * "chipax_clp": 9340000,
84481
+ * "vitrina_clp": 9340000,
84482
+ * "difference_clp": 0,
84483
+ * "difference_count": 0,
84484
+ * "rows": []
84485
+ * },
84486
+ * "income": {
84487
+ * "bridge": {
84488
+ * "vitrina_clp": 31500000,
84489
+ * "chipax_clp": 30100000,
84490
+ * "difference_clp": -1400000,
84491
+ * "explained": true,
84492
+ * "lines": [
84493
+ * {
84494
+ * "key": "timing_vitrina",
84495
+ * "label": "Emitidos en el mes que Chipax no cuenta en el mes (los cuenta al cobrarlos)",
84496
+ * "amount_clp": -2100000,
84497
+ * "item_count": 14
84498
+ * },
84499
+ * {
84500
+ * "key": "timing_chipax",
84501
+ * "label": "Documentos de otros meses que Chipax cuenta en este mes",
84502
+ * "amount_clp": 700000,
84503
+ * "item_count": 5
84504
+ * }
84505
+ * ]
84506
+ * },
84507
+ * "rows": [],
84508
+ * "production": null
84258
84509
  * }
84259
84510
  * }
84260
84511
  * }
84261
84512
  */
84262
84513
  "application/json": {
84263
- data: components["schemas"]["FinanzasChipaxStatus"];
84514
+ data: {
84515
+ month: string;
84516
+ label: string;
84517
+ /** @enum {string} */
84518
+ status: "not_read" | "reading" | "ready" | "failed";
84519
+ read: {
84520
+ /** Format: uuid */
84521
+ id: string;
84522
+ month: string;
84523
+ /** @enum {string} */
84524
+ status: "queued" | "running" | "done" | "failed";
84525
+ /** @description Payables are compared among documents issued since this day (the earliest Chipax import, else a year before the month). */
84526
+ history_from: string;
84527
+ error: string | null;
84528
+ requested_by: string | null;
84529
+ /** @description ISO 8601 timestamp. */
84530
+ started_at: string | null;
84531
+ /** @description ISO 8601 timestamp. */
84532
+ finished_at: string | null;
84533
+ /** @description ISO 8601 timestamp. */
84534
+ created_at: string;
84535
+ } | null;
84536
+ active_read: {
84537
+ /** Format: uuid */
84538
+ id: string;
84539
+ month: string;
84540
+ /** @enum {string} */
84541
+ status: "queued" | "running" | "done" | "failed";
84542
+ /** @description Payables are compared among documents issued since this day (the earliest Chipax import, else a year before the month). */
84543
+ history_from: string;
84544
+ error: string | null;
84545
+ requested_by: string | null;
84546
+ /** @description ISO 8601 timestamp. */
84547
+ started_at: string | null;
84548
+ /** @description ISO 8601 timestamp. */
84549
+ finished_at: string | null;
84550
+ /** @description ISO 8601 timestamp. */
84551
+ created_at: string;
84552
+ } | null;
84553
+ last_error: string | null;
84554
+ history_from: string | null;
84555
+ /** @description Balances, payables and costs match and the income bridge is fully explained: the exit criterion of the shadow month. */
84556
+ clean: boolean | null;
84557
+ warnings: string[];
84558
+ balances: {
84559
+ matches: boolean;
84560
+ difference_count: number;
84561
+ rows: {
84562
+ /** @description Pass as `key` to the items endpoint. */
84563
+ key: string;
84564
+ label: string;
84565
+ /** @description Whole CLP. */
84566
+ chipax_clp: number | null;
84567
+ /** @description Whole CLP. */
84568
+ vitrina_clp: number | null;
84569
+ /** @description Chipax − Vitrina. */
84570
+ difference_clp: number;
84571
+ /** @description Zero tolerance: equal figures AND every item pairs. */
84572
+ matches: boolean;
84573
+ item_count: number;
84574
+ difference_count: number;
84575
+ /**
84576
+ * @description paired: both sides have the account (zero tolerance). only_vitrina: Chipax never tracked it (e.g. Mercado Pago); shown, never breaks `clean`, difference_clp is 0 and it has no items. only_chipax: Vitrina lacks the account; breaks `clean`.
84577
+ * @enum {string}
84578
+ */
84579
+ side: "paired" | "only_vitrina" | "only_chipax";
84580
+ /**
84581
+ * @description closing = balances at month end; movements = the month's net movements (a side has no balance).
84582
+ * @enum {string}
84583
+ */
84584
+ basis: "closing" | "movements";
84585
+ vitrina_account: {
84586
+ id: string;
84587
+ name: string;
84588
+ institution_name: string | null;
84589
+ number_masked: string | null;
84590
+ } | null;
84591
+ chipax_account: {
84592
+ /** @description Chipax's id of the account. */
84593
+ external_id: string;
84594
+ name: string | null;
84595
+ bank: string | null;
84596
+ number_masked: string | null;
84597
+ } | null;
84598
+ movements: {
84599
+ /** @description Whole CLP. */
84600
+ chipax_in_clp: number;
84601
+ /** @description Whole CLP. */
84602
+ chipax_out_clp: number;
84603
+ /** @description Whole CLP. */
84604
+ vitrina_in_clp: number;
84605
+ /** @description Whole CLP. */
84606
+ vitrina_out_clp: number;
84607
+ };
84608
+ }[];
84609
+ } | null;
84610
+ payables: {
84611
+ matches: boolean;
84612
+ /** @description Whole CLP. */
84613
+ chipax_clp: number;
84614
+ /** @description Whole CLP. */
84615
+ vitrina_clp: number;
84616
+ /** @description Whole CLP. */
84617
+ difference_clp: number;
84618
+ difference_count: number;
84619
+ rows: {
84620
+ /** @description Pass as `key` to the items endpoint. */
84621
+ key: string;
84622
+ label: string;
84623
+ /** @description Whole CLP. */
84624
+ chipax_clp: number | null;
84625
+ /** @description Whole CLP. */
84626
+ vitrina_clp: number | null;
84627
+ /** @description Chipax − Vitrina. */
84628
+ difference_clp: number;
84629
+ /** @description Zero tolerance: equal figures AND every item pairs. */
84630
+ matches: boolean;
84631
+ item_count: number;
84632
+ difference_count: number;
84633
+ rut: string | null;
84634
+ contraparte_id: string | null;
84635
+ }[];
84636
+ } | null;
84637
+ costs: {
84638
+ matches: boolean;
84639
+ /** @description Whole CLP. */
84640
+ chipax_clp: number;
84641
+ /** @description Whole CLP. */
84642
+ vitrina_clp: number;
84643
+ /** @description Whole CLP. */
84644
+ difference_clp: number;
84645
+ difference_count: number;
84646
+ rows: {
84647
+ /** @description Pass as `key` to the items endpoint. */
84648
+ key: string;
84649
+ label: string;
84650
+ /** @description Whole CLP. */
84651
+ chipax_clp: number | null;
84652
+ /** @description Whole CLP. */
84653
+ vitrina_clp: number | null;
84654
+ /** @description Chipax − Vitrina. */
84655
+ difference_clp: number;
84656
+ /** @description Zero tolerance: equal figures AND every item pairs. */
84657
+ matches: boolean;
84658
+ item_count: number;
84659
+ difference_count: number;
84660
+ vitrina_account: {
84661
+ id: string;
84662
+ name: string;
84663
+ path: string;
84664
+ kind: string;
84665
+ } | null;
84666
+ chipax_accounts: {
84667
+ external_id: number;
84668
+ name: string;
84669
+ path: string;
84670
+ }[];
84671
+ }[];
84672
+ } | null;
84673
+ income: {
84674
+ bridge: {
84675
+ /** @description Whole CLP. */
84676
+ vitrina_clp: number;
84677
+ /** @description Whole CLP. */
84678
+ chipax_clp: number;
84679
+ /** @description Whole CLP. */
84680
+ difference_clp: number;
84681
+ explained: boolean;
84682
+ lines: {
84683
+ /** @enum {string} */
84684
+ key: "timing_vitrina" | "timing_chipax" | "document_not_in_vitrina" | "cash_without_document" | "amount_basis" | "unitemised";
84685
+ label: string;
84686
+ /** @description Whole CLP. */
84687
+ amount_clp: number;
84688
+ item_count: number;
84689
+ }[];
84690
+ };
84691
+ rows: {
84692
+ /** @description Pass as `key` to the items endpoint. */
84693
+ key: string;
84694
+ label: string;
84695
+ /** @description Whole CLP. */
84696
+ chipax_clp: number | null;
84697
+ /** @description Whole CLP. */
84698
+ vitrina_clp: number | null;
84699
+ /** @description Chipax − Vitrina. */
84700
+ difference_clp: number;
84701
+ /** @description Zero tolerance: equal figures AND every item pairs. */
84702
+ matches: boolean;
84703
+ item_count: number;
84704
+ difference_count: number;
84705
+ vitrina_account: {
84706
+ id: string;
84707
+ name: string;
84708
+ path: string;
84709
+ kind: string;
84710
+ } | null;
84711
+ chipax_accounts: {
84712
+ external_id: number;
84713
+ name: string;
84714
+ path: string;
84715
+ }[];
84716
+ }[];
84717
+ production: {
84718
+ /** @description Whole CLP. */
84719
+ produccion_clp: number;
84720
+ /** @description Whole CLP. */
84721
+ por_cobrar_clp: number;
84722
+ /** @description Whole CLP. */
84723
+ anticipos_clp: number;
84724
+ /** @description Whole CLP. */
84725
+ cobrado_clp: number;
84726
+ /** @description Whole CLP. */
84727
+ boleteado_clp: number;
84728
+ /** @description Whole CLP. */
84729
+ cobrado_sin_boleta_clp: number;
84730
+ /** @description Whole CLP. */
84731
+ boletas_sin_pago_clp: number;
84732
+ } | null;
84733
+ } | null;
84734
+ };
84735
+ };
84736
+ };
84737
+ };
84738
+ /** @description Validation error */
84739
+ 400: {
84740
+ headers: {
84741
+ [name: string]: unknown;
84742
+ };
84743
+ content: {
84744
+ "application/json": components["schemas"]["Error"];
84745
+ };
84746
+ };
84747
+ /** @description Unauthorized */
84748
+ 401: {
84749
+ headers: {
84750
+ [name: string]: unknown;
84751
+ };
84752
+ content: {
84753
+ "application/json": components["schemas"]["Error"];
84754
+ };
84755
+ };
84756
+ /** @description Forbidden */
84757
+ 403: {
84758
+ headers: {
84759
+ [name: string]: unknown;
84760
+ };
84761
+ content: {
84762
+ "application/json": components["schemas"]["Error"];
84763
+ };
84764
+ };
84765
+ /** @description Not found */
84766
+ 404: {
84767
+ headers: {
84768
+ [name: string]: unknown;
84769
+ };
84770
+ content: {
84771
+ "application/json": components["schemas"]["Error"];
84772
+ };
84773
+ };
84774
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
84775
+ 409: {
84776
+ headers: {
84777
+ [name: string]: unknown;
84778
+ };
84779
+ content: {
84780
+ "application/json": components["schemas"]["Error"];
84781
+ };
84782
+ };
84783
+ /** @description Rate limited */
84784
+ 429: {
84785
+ headers: {
84786
+ [name: string]: unknown;
84787
+ };
84788
+ content: {
84789
+ "application/json": components["schemas"]["Error"];
84790
+ };
84791
+ };
84792
+ };
84793
+ };
84794
+ put?: never;
84795
+ post?: never;
84796
+ delete?: never;
84797
+ options?: never;
84798
+ head?: never;
84799
+ patch?: never;
84800
+ trace?: never;
84801
+ };
84802
+ "/finanzas/chipax/shadow/{month}/items": {
84803
+ parameters: {
84804
+ query?: never;
84805
+ header?: never;
84806
+ path?: never;
84807
+ cookie?: never;
84808
+ };
84809
+ /**
84810
+ * Mes en sombra: the items behind a row
84811
+ * @description The items of one row of the diff (`key` from the diff; `bridge:<line>` for an income bridge line), both sides side by side, biggest difference first. By default only the items that do not match. A caller without the patient register (the Contador) sees a patient as «Paciente A. P.» with no RUT and no glosa, on both sides; Chipax boletas carry neither RUT nor name. Requires the `finanzas` add-on — without it every Finanzas operation answers `402 ENTITLEMENT_NOT_ACTIVE` (`details.required = ["finanzas"]`). Requires `finanzas:read` and `finanzas_reports:read` (the Contador seat, owners and admins). 404 before a finished read.
84812
+ */
84813
+ get: {
84814
+ parameters: {
84815
+ query: {
84816
+ dimension: "balances" | "payables" | "costs" | "income";
84817
+ key?: string;
84818
+ status?: "differences" | "all";
84819
+ limit?: number;
84820
+ offset?: number | null;
84821
+ };
84822
+ header?: never;
84823
+ path: {
84824
+ month: string;
84825
+ };
84826
+ cookie?: never;
84827
+ };
84828
+ requestBody?: never;
84829
+ responses: {
84830
+ /** @description Items */
84831
+ 200: {
84832
+ headers: {
84833
+ [name: string]: unknown;
84834
+ };
84835
+ content: {
84836
+ /**
84837
+ * @example {
84838
+ * "data": {
84839
+ * "month": "2026-10",
84840
+ * "dimension": "payables",
84841
+ * "key": "p_0000000000000001",
84842
+ * "items": [
84843
+ * {
84844
+ * "key": "chipax:compra:9002",
84845
+ * "row_key": "p_0000000000000001",
84846
+ * "other_row_key": null,
84847
+ * "status": "chipax_only",
84848
+ * "chipax": {
84849
+ * "type": "document",
84850
+ * "id": null,
84851
+ * "chipax_ref": "compra:9002",
84852
+ * "label": "Factura electrónica N° 452",
84853
+ * "dte_type": 33,
84854
+ * "day": "2026-10-05",
84855
+ * "amount_clp": 410000,
84856
+ * "counterparty_name": "Laboratorio Dental Andes Ltda",
84857
+ * "counterparty_rut": "76086428-5",
84858
+ * "description": null
84859
+ * },
84860
+ * "vitrina": null,
84861
+ * "vitrina_document_id": null,
84862
+ * "difference_clp": 410000,
84863
+ * "bridge_line": null
84864
+ * }
84865
+ * ],
84866
+ * "total": 1,
84867
+ * "limit": 50,
84868
+ * "offset": 0,
84869
+ * "difference_clp": 410000
84870
+ * }
84871
+ * }
84872
+ */
84873
+ "application/json": {
84874
+ data: {
84875
+ month: string;
84876
+ /** @enum {string} */
84877
+ dimension: "balances" | "payables" | "costs" | "income";
84878
+ key: string | null;
84879
+ items: {
84880
+ key: string;
84881
+ row_key: string;
84882
+ other_row_key: string | null;
84883
+ /**
84884
+ * @description match; chipax_only / vitrina_only; amount = both, different amounts; other_row = the other side has it under another row (account or Contraparte); unitemised = Chipax's total holds pesos with no item behind them.
84885
+ * @enum {string}
84886
+ */
84887
+ status: "match" | "chipax_only" | "vitrina_only" | "amount" | "other_row" | "unitemised";
84888
+ chipax: {
84889
+ /** @enum {string} */
84890
+ type: "document" | "movement" | "total";
84891
+ /** @description Vitrina: the document or bank movement id. Chipax: null. */
84892
+ id: string | null;
84893
+ /** @description Chipax: `<model>:<id>` or `cartola:<id>`. Vitrina: null. */
84894
+ chipax_ref: string | null;
84895
+ /** @description «Factura electrónica N° 451». */
84896
+ label: string;
84897
+ dte_type: number | null;
84898
+ day: string | null;
84899
+ /** @description Signed, as the dimension counts it (money in +, out −, on balances). */
84900
+ amount_clp: number;
84901
+ counterparty_name: string | null;
84902
+ counterparty_rut: string | null;
84903
+ description: string | null;
84904
+ } | null;
84905
+ vitrina: {
84906
+ /** @enum {string} */
84907
+ type: "document" | "movement" | "total";
84908
+ /** @description Vitrina: the document or bank movement id. Chipax: null. */
84909
+ id: string | null;
84910
+ /** @description Chipax: `<model>:<id>` or `cartola:<id>`. Vitrina: null. */
84911
+ chipax_ref: string | null;
84912
+ /** @description «Factura electrónica N° 451». */
84913
+ label: string;
84914
+ dte_type: number | null;
84915
+ day: string | null;
84916
+ /** @description Signed, as the dimension counts it (money in +, out −, on balances). */
84917
+ amount_clp: number;
84918
+ counterparty_name: string | null;
84919
+ counterparty_rut: string | null;
84920
+ description: string | null;
84921
+ } | null;
84922
+ vitrina_document_id: string | null;
84923
+ /** @description Chipax − Vitrina. */
84924
+ difference_clp: number;
84925
+ /** @enum {string|null} */
84926
+ bridge_line: "timing_vitrina" | "timing_chipax" | "document_not_in_vitrina" | "cash_without_document" | "amount_basis" | "unitemised" | null;
84927
+ }[];
84928
+ total: number;
84929
+ limit: number;
84930
+ offset: number;
84931
+ /** @description Whole CLP. */
84932
+ difference_clp: number;
84933
+ };
84934
+ };
84935
+ };
84936
+ };
84937
+ /** @description Validation error */
84938
+ 400: {
84939
+ headers: {
84940
+ [name: string]: unknown;
84941
+ };
84942
+ content: {
84943
+ "application/json": components["schemas"]["Error"];
84944
+ };
84945
+ };
84946
+ /** @description Unauthorized */
84947
+ 401: {
84948
+ headers: {
84949
+ [name: string]: unknown;
84950
+ };
84951
+ content: {
84952
+ "application/json": components["schemas"]["Error"];
84953
+ };
84954
+ };
84955
+ /** @description Forbidden */
84956
+ 403: {
84957
+ headers: {
84958
+ [name: string]: unknown;
84959
+ };
84960
+ content: {
84961
+ "application/json": components["schemas"]["Error"];
84962
+ };
84963
+ };
84964
+ /** @description Not found */
84965
+ 404: {
84966
+ headers: {
84967
+ [name: string]: unknown;
84968
+ };
84969
+ content: {
84970
+ "application/json": components["schemas"]["Error"];
84971
+ };
84972
+ };
84973
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
84974
+ 409: {
84975
+ headers: {
84976
+ [name: string]: unknown;
84977
+ };
84978
+ content: {
84979
+ "application/json": components["schemas"]["Error"];
84980
+ };
84981
+ };
84982
+ /** @description Rate limited */
84983
+ 429: {
84984
+ headers: {
84985
+ [name: string]: unknown;
84986
+ };
84987
+ content: {
84988
+ "application/json": components["schemas"]["Error"];
84989
+ };
84990
+ };
84991
+ };
84992
+ };
84993
+ put?: never;
84994
+ post?: never;
84995
+ delete?: never;
84996
+ options?: never;
84997
+ head?: never;
84998
+ patch?: never;
84999
+ trace?: never;
85000
+ };
85001
+ "/finanzas/chipax/shadow/{month}/export": {
85002
+ parameters: {
85003
+ query?: never;
85004
+ header?: never;
85005
+ path?: never;
85006
+ cookie?: never;
85007
+ };
85008
+ /**
85009
+ * Mes en sombra: download the diff (xlsx)
85010
+ * @description One workbook: «Resumen», «Saldos bancarios», «Por pagar», «Costos y gastos», «Puente de ingresos» and «Diferencias» (every item that does not match, all dimensions). A caller without the patient register (the Contador) sees a patient as «Paciente A. P.» with no RUT and no glosa, on both sides; Chipax boletas carry neither RUT nor name. Requires the `finanzas` add-on — without it every Finanzas operation answers `402 ENTITLEMENT_NOT_ACTIVE` (`details.required = ["finanzas"]`). Requires `finanzas:read`, `finanzas_reports:read` and `finanzas:export`. 404 before a finished read.
85011
+ */
85012
+ get: {
85013
+ parameters: {
85014
+ query?: never;
85015
+ header?: never;
85016
+ path: {
85017
+ month: string;
85018
+ };
85019
+ cookie?: never;
85020
+ };
85021
+ requestBody?: never;
85022
+ responses: {
85023
+ /** @description The workbook, as an attachment */
85024
+ 200: {
85025
+ headers: {
85026
+ [name: string]: unknown;
85027
+ };
85028
+ content: {
85029
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": string;
85030
+ };
85031
+ };
85032
+ /** @description Validation error */
85033
+ 400: {
85034
+ headers: {
85035
+ [name: string]: unknown;
85036
+ };
85037
+ content: {
85038
+ "application/json": components["schemas"]["Error"];
85039
+ };
85040
+ };
85041
+ /** @description Unauthorized */
85042
+ 401: {
85043
+ headers: {
85044
+ [name: string]: unknown;
85045
+ };
85046
+ content: {
85047
+ "application/json": components["schemas"]["Error"];
85048
+ };
85049
+ };
85050
+ /** @description Forbidden */
85051
+ 403: {
85052
+ headers: {
85053
+ [name: string]: unknown;
85054
+ };
85055
+ content: {
85056
+ "application/json": components["schemas"]["Error"];
85057
+ };
85058
+ };
85059
+ /** @description Not found */
85060
+ 404: {
85061
+ headers: {
85062
+ [name: string]: unknown;
85063
+ };
85064
+ content: {
85065
+ "application/json": components["schemas"]["Error"];
85066
+ };
85067
+ };
85068
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
85069
+ 409: {
85070
+ headers: {
85071
+ [name: string]: unknown;
85072
+ };
85073
+ content: {
85074
+ "application/json": components["schemas"]["Error"];
85075
+ };
85076
+ };
85077
+ /** @description Rate limited */
85078
+ 429: {
85079
+ headers: {
85080
+ [name: string]: unknown;
85081
+ };
85082
+ content: {
85083
+ "application/json": components["schemas"]["Error"];
85084
+ };
85085
+ };
85086
+ };
85087
+ };
85088
+ put?: never;
85089
+ post?: never;
85090
+ delete?: never;
85091
+ options?: never;
85092
+ head?: never;
85093
+ patch?: never;
85094
+ trace?: never;
85095
+ };
85096
+ "/finanzas/chipax": {
85097
+ parameters: {
85098
+ query?: never;
85099
+ header?: never;
85100
+ path?: never;
85101
+ cookie?: never;
85102
+ };
85103
+ /**
85104
+ * Importar desde Chipax: connection and runs
85105
+ * @description Whether the workspace stored its Chipax API credentials (only a masked App ID hint, never the secret), the run in progress and the last finished one. Vitrina only READS Chipax: it logs in and sends GET requests; it never creates, edits or deletes anything in the Chipax account. Requires the `finanzas` add-on — without it every Finanzas operation answers `402 ENTITLEMENT_NOT_ACTIVE` (`details.required = ["finanzas"]`). Requires `finanzas:read`.
85106
+ */
85107
+ get: {
85108
+ parameters: {
85109
+ query?: never;
85110
+ header?: never;
85111
+ path?: never;
85112
+ cookie?: never;
85113
+ };
85114
+ requestBody?: never;
85115
+ responses: {
85116
+ /** @description Connection and runs */
85117
+ 200: {
85118
+ headers: {
85119
+ [name: string]: unknown;
85120
+ };
85121
+ content: {
85122
+ /**
85123
+ * @example {
85124
+ * "data": {
85125
+ * "connected": true,
85126
+ * "app_id_preview": "a1b…9f2",
85127
+ * "verified_at": "2026-10-30T21:58:40.000Z",
85128
+ * "active_import": null,
85129
+ * "last_import": {
85130
+ * "id": "0190a3c2-5d1e-7b6a-9f20-4c1d2e3f5a16",
85131
+ * "mode": "dry_run",
85132
+ * "status": "done",
85133
+ * "from": "2025-01-01",
85134
+ * "to": "2026-10-30",
85135
+ * "account_map": [],
85136
+ * "requested_by": "0190a3c2-5d1e-7b6a-9f20-4c1d2e3f4f01",
85137
+ * "error": null,
85138
+ * "started_at": "2026-10-30T22:01:04.000Z",
85139
+ * "finished_at": "2026-10-30T22:14:51.000Z",
85140
+ * "created_at": "2026-10-30T22:01:02.000Z",
85141
+ * "report": null
85142
+ * }
85143
+ * }
85144
+ * }
85145
+ */
85146
+ "application/json": {
85147
+ data: components["schemas"]["FinanzasChipaxStatus"];
85148
+ };
85149
+ };
85150
+ };
85151
+ /** @description Validation error */
85152
+ 400: {
85153
+ headers: {
85154
+ [name: string]: unknown;
85155
+ };
85156
+ content: {
85157
+ "application/json": components["schemas"]["Error"];
85158
+ };
85159
+ };
85160
+ /** @description Unauthorized */
85161
+ 401: {
85162
+ headers: {
85163
+ [name: string]: unknown;
85164
+ };
85165
+ content: {
85166
+ "application/json": components["schemas"]["Error"];
85167
+ };
85168
+ };
85169
+ /** @description Forbidden */
85170
+ 403: {
85171
+ headers: {
85172
+ [name: string]: unknown;
85173
+ };
85174
+ content: {
85175
+ "application/json": components["schemas"]["Error"];
85176
+ };
85177
+ };
85178
+ /** @description Not found */
85179
+ 404: {
85180
+ headers: {
85181
+ [name: string]: unknown;
85182
+ };
85183
+ content: {
85184
+ "application/json": components["schemas"]["Error"];
85185
+ };
85186
+ };
85187
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
85188
+ 409: {
85189
+ headers: {
85190
+ [name: string]: unknown;
85191
+ };
85192
+ content: {
85193
+ "application/json": components["schemas"]["Error"];
85194
+ };
85195
+ };
85196
+ /** @description Rate limited */
85197
+ 429: {
85198
+ headers: {
85199
+ [name: string]: unknown;
85200
+ };
85201
+ content: {
85202
+ "application/json": components["schemas"]["Error"];
85203
+ };
85204
+ };
85205
+ };
85206
+ };
85207
+ put?: never;
85208
+ post?: never;
85209
+ delete?: never;
85210
+ options?: never;
85211
+ head?: never;
85212
+ patch?: never;
85213
+ trace?: never;
85214
+ };
85215
+ "/finanzas/chipax/credentials": {
85216
+ parameters: {
85217
+ query?: never;
85218
+ header?: never;
85219
+ path?: never;
85220
+ cookie?: never;
85221
+ };
85222
+ get?: never;
85223
+ put?: never;
85224
+ post?: never;
85225
+ /**
85226
+ * Importar desde Chipax: «Eliminar credenciales»
85227
+ * @description Deletes the stored Chipax credentials. What was already imported stays. Idempotent. Requires the `finanzas` add-on — without it every Finanzas operation answers `402 ENTITLEMENT_NOT_ACTIVE` (`details.required = ["finanzas"]`). Requires `finanzas_admin:write`.
85228
+ */
85229
+ delete: {
85230
+ parameters: {
85231
+ query?: never;
85232
+ header?: never;
85233
+ path?: never;
85234
+ cookie?: never;
85235
+ };
85236
+ requestBody?: never;
85237
+ responses: {
85238
+ /** @description Deleted */
85239
+ 200: {
85240
+ headers: {
85241
+ [name: string]: unknown;
85242
+ };
85243
+ content: {
85244
+ /**
85245
+ * @example {
85246
+ * "data": {
85247
+ * "connected": false,
85248
+ * "app_id_preview": null,
85249
+ * "verified_at": null,
85250
+ * "active_import": null,
85251
+ * "last_import": {
85252
+ * "id": "0190a3c2-5d1e-7b6a-9f20-4c1d2e3f5a16",
85253
+ * "mode": "dry_run",
85254
+ * "status": "done",
85255
+ * "from": "2025-01-01",
85256
+ * "to": "2026-10-30",
85257
+ * "account_map": [],
85258
+ * "requested_by": "0190a3c2-5d1e-7b6a-9f20-4c1d2e3f4f01",
85259
+ * "error": null,
85260
+ * "started_at": "2026-10-30T22:01:04.000Z",
85261
+ * "finished_at": "2026-10-30T22:14:51.000Z",
85262
+ * "created_at": "2026-10-30T22:01:02.000Z",
85263
+ * "report": null
85264
+ * }
85265
+ * }
85266
+ * }
85267
+ */
85268
+ "application/json": {
85269
+ data: components["schemas"]["FinanzasChipaxStatus"];
84264
85270
  };
84265
85271
  };
84266
85272
  };
@@ -86135,6 +87141,7 @@ interface paths {
86135
87141
  query?: {
86136
87142
  from?: string;
86137
87143
  to?: string;
87144
+ horizon_days?: number;
86138
87145
  granularity?: "day" | "week";
86139
87146
  };
86140
87147
  header?: never;
@@ -86265,6 +87272,10 @@ interface paths {
86265
87272
  * "receivables_clp": 0,
86266
87273
  * "receivables_count": 0
86267
87274
  * },
87275
+ * "typical_income": {
87276
+ * "basis": "history",
87277
+ * "weeks": 12
87278
+ * },
86268
87279
  * "band_basis": {
86269
87280
  * "from": "2026-08-01",
86270
87281
  * "to": "2026-10-29",
@@ -86611,6 +87622,7 @@ interface paths {
86611
87622
  parameters: {
86612
87623
  query?: {
86613
87624
  dry_run?: "true" | "false";
87625
+ horizon_days?: number;
86614
87626
  };
86615
87627
  header?: {
86616
87628
  /** @description Replay-safe retries: resending the SAME key with the SAME body returns the original response (`X-Idempotent-Replay: 1`) instead of creating a second copy — safe to send whenever a response might not have arrived. The same key with a DIFFERENT body answers `409 IDEMPOTENCY_KEY_CONFLICT`; use a fresh key per operation. */
@@ -86721,6 +87733,10 @@ interface paths {
86721
87733
  * "high_clp": 4020000
86722
87734
  * }
86723
87735
  * }
87736
+ * },
87737
+ * "horizon": {
87738
+ * "days": 30,
87739
+ * "to": "2026-11-30"
86724
87740
  * }
86725
87741
  * }
86726
87742
  * }
@@ -86809,7 +87825,9 @@ interface paths {
86809
87825
  */
86810
87826
  delete: {
86811
87827
  parameters: {
86812
- query?: never;
87828
+ query?: {
87829
+ horizon_days?: number;
87830
+ };
86813
87831
  header?: never;
86814
87832
  path: {
86815
87833
  id: string;
@@ -86899,6 +87917,10 @@ interface paths {
86899
87917
  * "high_clp": 4020000
86900
87918
  * }
86901
87919
  * }
87920
+ * },
87921
+ * "horizon": {
87922
+ * "days": 30,
87923
+ * "to": "2026-11-30"
86902
87924
  * }
86903
87925
  * }
86904
87926
  * }
@@ -86987,6 +88009,7 @@ interface paths {
86987
88009
  parameters: {
86988
88010
  query?: {
86989
88011
  dry_run?: "true" | "false";
88012
+ horizon_days?: number;
86990
88013
  };
86991
88014
  header?: {
86992
88015
  /** @description Replay-safe retries: resending the SAME key with the SAME body returns the original response (`X-Idempotent-Replay: 1`) instead of creating a second copy — safe to send whenever a response might not have arrived. The same key with a DIFFERENT body answers `409 IDEMPOTENCY_KEY_CONFLICT`; use a fresh key per operation. */
@@ -87083,6 +88106,10 @@ interface paths {
87083
88106
  * "high_clp": 4020000
87084
88107
  * }
87085
88108
  * }
88109
+ * },
88110
+ * "horizon": {
88111
+ * "days": 30,
88112
+ * "to": "2026-11-30"
87086
88113
  * }
87087
88114
  * }
87088
88115
  * }
@@ -87176,6 +88203,10 @@ interface paths {
87176
88203
  * "high_clp": 4020000
87177
88204
  * }
87178
88205
  * }
88206
+ * },
88207
+ * "horizon": {
88208
+ * "days": 30,
88209
+ * "to": "2026-11-30"
87179
88210
  * }
87180
88211
  * }
87181
88212
  * }
@@ -87992,6 +89023,156 @@ interface paths {
87992
89023
  patch?: never;
87993
89024
  trace?: never;
87994
89025
  };
89026
+ "/finanzas/digest/preview": {
89027
+ parameters: {
89028
+ query?: never;
89029
+ header?: never;
89030
+ path?: never;
89031
+ cookie?: never;
89032
+ };
89033
+ /**
89034
+ * Preview the weekly Finanzas digest
89035
+ * @description What this week's «Resumen semanal de Finanzas» says to the caller, read now from the Resumen (`GET /finanzas/resumen`), so the figures match the home. The digest goes out every Monday from 09:00 workspace time, at most once per workspace and week, to every member with `finanzas:read`: email by default, WhatsApp only on the opt-in `finanzas_whatsapp` rail; each member turns it off in their notification preferences (`finanzas.weekly_digest`). A workspace with no finance data gets none (`will_send: false`). Without `finanzas_reports:read` there are no cash or result figures; without the patient roster patients read as initials. Sends nothing. Requires the `finanzas` add-on (402 `ENTITLEMENT_NOT_ACTIVE` otherwise) and `finanzas:read`.
89036
+ */
89037
+ get: {
89038
+ parameters: {
89039
+ query?: never;
89040
+ header?: never;
89041
+ path?: never;
89042
+ cookie?: never;
89043
+ };
89044
+ requestBody?: never;
89045
+ responses: {
89046
+ /** @description The digest as the caller would read it this week */
89047
+ 200: {
89048
+ headers: {
89049
+ [name: string]: unknown;
89050
+ };
89051
+ content: {
89052
+ /**
89053
+ * @example {
89054
+ * "data": {
89055
+ * "week_start": "2026-11-02",
89056
+ * "send_at": "2026-11-02T12:00:00.000Z",
89057
+ * "next_send_at": "2026-11-09T12:00:00.000Z",
89058
+ * "status": "pending",
89059
+ * "sent_at": null,
89060
+ * "will_send": true,
89061
+ * "channels": {
89062
+ * "email": true,
89063
+ * "whatsapp": false
89064
+ * },
89065
+ * "email": {
89066
+ * "subject": "Resumen semanal de Finanzas: $12.340.000 en caja",
89067
+ * "hero": {
89068
+ * "label": "Caja hoy",
89069
+ * "value": "$12.340.000",
89070
+ * "caption": "A fin de mes: $8.200.000. En 30 días: $9.100.000."
89071
+ * },
89072
+ * "problem": {
89073
+ * "text": "La caja alcanza hasta el 23 de noviembre. Ese martes pagas Arriendo y quedarías en negativo por $450.000.",
89074
+ * "link": {
89075
+ * "label": "Ver flujo de caja y cómo cubrirlo",
89076
+ * "path": "/finanzas/reportes/flujo-de-caja"
89077
+ * }
89078
+ * },
89079
+ * "lines": [
89080
+ * "Noviembre va en $6.100.000 de ingresos, de $9.800.000 para cubrir costos. Por ahora el mes pierde $1.200.000.",
89081
+ * "3 casos te necesitan en Por resolver, por $840.000."
89082
+ * ],
89083
+ * "primary": {
89084
+ * "label": "Ver Resumen",
89085
+ * "path": "/finanzas"
89086
+ * },
89087
+ * "secondary": {
89088
+ * "label": "Ir a Por resolver",
89089
+ * "path": "/finanzas/por-resolver"
89090
+ * }
89091
+ * },
89092
+ * "whatsapp_text": "Caja hoy: $12.340.000. La caja alcanza hasta el 23 de noviembre. Ese martes pagas Arriendo y quedarías en negativo por $450.000. 3 casos te necesitan en Por resolver, por $840.000.",
89093
+ * "figures": {
89094
+ * "reports_visible": true,
89095
+ * "cash_today_clp": 12340000,
89096
+ * "month_end_clp": 8200000,
89097
+ * "in_30_days_clp": 9100000,
89098
+ * "runs_out_date": "2026-11-24",
89099
+ * "ingresos_clp": 6100000,
89100
+ * "resultado_clp": -1200000,
89101
+ * "equilibrio_clp": 9800000,
89102
+ * "open_cases": 3
89103
+ * }
89104
+ * }
89105
+ * }
89106
+ */
89107
+ "application/json": {
89108
+ data: components["schemas"]["FinanzasDigestPreview"];
89109
+ };
89110
+ };
89111
+ };
89112
+ /** @description Validation error */
89113
+ 400: {
89114
+ headers: {
89115
+ [name: string]: unknown;
89116
+ };
89117
+ content: {
89118
+ "application/json": components["schemas"]["Error"];
89119
+ };
89120
+ };
89121
+ /** @description Unauthorized */
89122
+ 401: {
89123
+ headers: {
89124
+ [name: string]: unknown;
89125
+ };
89126
+ content: {
89127
+ "application/json": components["schemas"]["Error"];
89128
+ };
89129
+ };
89130
+ /** @description Forbidden */
89131
+ 403: {
89132
+ headers: {
89133
+ [name: string]: unknown;
89134
+ };
89135
+ content: {
89136
+ "application/json": components["schemas"]["Error"];
89137
+ };
89138
+ };
89139
+ /** @description Not found */
89140
+ 404: {
89141
+ headers: {
89142
+ [name: string]: unknown;
89143
+ };
89144
+ content: {
89145
+ "application/json": components["schemas"]["Error"];
89146
+ };
89147
+ };
89148
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
89149
+ 409: {
89150
+ headers: {
89151
+ [name: string]: unknown;
89152
+ };
89153
+ content: {
89154
+ "application/json": components["schemas"]["Error"];
89155
+ };
89156
+ };
89157
+ /** @description Rate limited */
89158
+ 429: {
89159
+ headers: {
89160
+ [name: string]: unknown;
89161
+ };
89162
+ content: {
89163
+ "application/json": components["schemas"]["Error"];
89164
+ };
89165
+ };
89166
+ };
89167
+ };
89168
+ put?: never;
89169
+ post?: never;
89170
+ delete?: never;
89171
+ options?: never;
89172
+ head?: never;
89173
+ patch?: never;
89174
+ trace?: never;
89175
+ };
87995
89176
  "/finanzas/costos": {
87996
89177
  parameters: {
87997
89178
  query?: never;
@@ -88477,6 +89658,328 @@ interface paths {
88477
89658
  };
88478
89659
  trace?: never;
88479
89660
  };
89661
+ "/finanzas/resumen": {
89662
+ parameters: {
89663
+ query?: never;
89664
+ header?: never;
89665
+ path?: never;
89666
+ cookie?: never;
89667
+ };
89668
+ /**
89669
+ * Resumen: the Finanzas home, three answers and the context
89670
+ * @description The Finanzas home in one read, every figure from its detail screen: **cash** («¿cuánto me queda a fin de mes?») = the Flujo de caja projection — today’s balance of the operating accounts, the month-end and 30-day balance, the lowest point and `runs_out` (the first day under zero within 30 days, with its biggest payment); **result** («¿cuánto gasto? / ¿este mes gana plata?») = Costos y equilibrio for the current month at net amounts (ingresos, gastos = variables + fijos, «sin clasificar» apart and counted as variable, resultado operacional) against the punto de equilibrio of the last closed month; **inbox** («Te necesita») = the open «Por resolver» cases and the previous month’s close state; **automatic** = this month’s «Hecho por Vitrina» totals and the newest 3; **accounts** with their balances. `problem` is the one thing shown in red (cash running out, else a bank connection that needs a person). A caller without `finanzas_reports:read` gets `cash` and `result` null (`reports_visible: false`). A Contador sees patients as initials. Requires the `finanzas` add-on — without it every Finanzas operation answers `402 ENTITLEMENT_NOT_ACTIVE` (`details.required = ["finanzas"]`). Requires `finanzas:read`.
89671
+ */
89672
+ get: {
89673
+ parameters: {
89674
+ query?: never;
89675
+ header?: never;
89676
+ path?: never;
89677
+ cookie?: never;
89678
+ };
89679
+ requestBody?: never;
89680
+ responses: {
89681
+ /** @description The Resumen */
89682
+ 200: {
89683
+ headers: {
89684
+ [name: string]: unknown;
89685
+ };
89686
+ content: {
89687
+ /**
89688
+ * @example {
89689
+ * "data": {
89690
+ * "as_of": "2026-10-30",
89691
+ * "month": "2026-10",
89692
+ * "month_label": "octubre 2026",
89693
+ * "currency": "CLP",
89694
+ * "reports_visible": true,
89695
+ * "synced_at": "2026-10-30T11:02:00.000Z",
89696
+ * "problem": {
89697
+ * "kind": "cash_runs_out",
89698
+ * "date": "2026-11-06",
89699
+ * "balance_clp": -412000
89700
+ * },
89701
+ * "cash": {
89702
+ * "today_clp": 4917109,
89703
+ * "balance_as_of": "2026-10-30T11:02:00.000Z",
89704
+ * "accounts_count": 3,
89705
+ * "unknown_count": 0,
89706
+ * "savings_clp": 12000000,
89707
+ * "month_end": {
89708
+ * "date": "2026-10-31",
89709
+ * "balance_clp": 5102000,
89710
+ * "band": {
89711
+ * "low_clp": 4980000,
89712
+ * "high_clp": 5260000
89713
+ * }
89714
+ * },
89715
+ * "in_30_days": {
89716
+ * "date": "2026-11-29",
89717
+ * "balance_clp": 3880000,
89718
+ * "band": {
89719
+ * "low_clp": 2100000,
89720
+ * "high_clp": 5400000
89721
+ * }
89722
+ * },
89723
+ * "lowest": {
89724
+ * "date": "2026-11-06",
89725
+ * "balance_clp": -412000,
89726
+ * "negative": true,
89727
+ * "cause": {
89728
+ * "key": "document:0190a3c2-5d1e-7b6a-9f20-4c1d2e3f6501",
89729
+ * "source": "payable",
89730
+ * "direction": "outflow",
89731
+ * "label": "Factura 4410 · Laboratorio Andes SpA",
89732
+ * "amount_clp": 5800000,
89733
+ * "date": "2026-11-06",
89734
+ * "due_date": "2026-11-06",
89735
+ * "overdue": false,
89736
+ * "movable": true,
89737
+ * "move": null,
89738
+ * "document": {
89739
+ * "id": "0190a3c2-5d1e-7b6a-9f20-4c1d2e3f6501",
89740
+ * "kind": "purchase",
89741
+ * "dte_type": 33,
89742
+ * "folio": "4410"
89743
+ * },
89744
+ * "contraparte": {
89745
+ * "id": "0190a3c2-5d1e-7b6a-9f20-4c1d2e3f6601",
89746
+ * "name": "Laboratorio Andes SpA"
89747
+ * },
89748
+ * "recurring_item_id": null,
89749
+ * "rescue_id": null,
89750
+ * "count": null
89751
+ * }
89752
+ * },
89753
+ * "runs_out": {
89754
+ * "date": "2026-11-06",
89755
+ * "covered_until": "2026-11-05",
89756
+ * "balance_clp": -412000,
89757
+ * "cause": {
89758
+ * "key": "document:0190a3c2-5d1e-7b6a-9f20-4c1d2e3f6501",
89759
+ * "source": "payable",
89760
+ * "direction": "outflow",
89761
+ * "label": "Factura 4410 · Laboratorio Andes SpA",
89762
+ * "amount_clp": 5800000,
89763
+ * "date": "2026-11-06",
89764
+ * "due_date": "2026-11-06",
89765
+ * "overdue": false,
89766
+ * "movable": true,
89767
+ * "move": null,
89768
+ * "document": {
89769
+ * "id": "0190a3c2-5d1e-7b6a-9f20-4c1d2e3f6501",
89770
+ * "kind": "purchase",
89771
+ * "dte_type": 33,
89772
+ * "folio": "4410"
89773
+ * },
89774
+ * "contraparte": {
89775
+ * "id": "0190a3c2-5d1e-7b6a-9f20-4c1d2e3f6601",
89776
+ * "name": "Laboratorio Andes SpA"
89777
+ * },
89778
+ * "recurring_item_id": null,
89779
+ * "rescue_id": null,
89780
+ * "count": null
89781
+ * }
89782
+ * },
89783
+ * "overdue": {
89784
+ * "payables_clp": 0,
89785
+ * "payables_count": 0,
89786
+ * "stale_payables_clp": 0,
89787
+ * "stale_payables_count": 0,
89788
+ * "receivables_clp": 380000,
89789
+ * "receivables_count": 2
89790
+ * },
89791
+ * "points": [
89792
+ * {
89793
+ * "date": "2026-10-30",
89794
+ * "balance_clp": 4917109,
89795
+ * "band": {
89796
+ * "low_clp": 4917109,
89797
+ * "high_clp": 4917109
89798
+ * }
89799
+ * },
89800
+ * {
89801
+ * "date": "2026-10-31",
89802
+ * "balance_clp": 5102000,
89803
+ * "band": {
89804
+ * "low_clp": 4980000,
89805
+ * "high_clp": 5260000
89806
+ * }
89807
+ * }
89808
+ * ]
89809
+ * },
89810
+ * "result": {
89811
+ * "month": "2026-10",
89812
+ * "label": "octubre 2026",
89813
+ * "proforma": true,
89814
+ * "ingresos_clp": 41200000,
89815
+ * "gastos_clp": 38900000,
89816
+ * "variables_clp": 17400000,
89817
+ * "fijos_clp": 21500000,
89818
+ * "sin_clasificar_clp": 900000,
89819
+ * "resultado_clp": 2300000,
89820
+ * "equilibrio": {
89821
+ * "month": "2026-09",
89822
+ * "label": "septiembre 2026",
89823
+ * "equilibrio_clp": 44600000,
89824
+ * "sin_calculo": null
89825
+ * },
89826
+ * "cobertura_pct": 92.4,
89827
+ * "brecha_clp": -3400000
89828
+ * },
89829
+ * "inbox": {
89830
+ * "open": 4,
89831
+ * "amount_at_stake_clp": 2860000,
89832
+ * "by_kind": {
89833
+ * "reconcile": 2,
89834
+ * "transfer": 0,
89835
+ * "classify": 1,
89836
+ * "missing_document": 1,
89837
+ * "unknown": 0
89838
+ * },
89839
+ * "close": {
89840
+ * "month": "2026-09",
89841
+ * "label": "septiembre 2026",
89842
+ * "state": "closed",
89843
+ * "open_cases": 0
89844
+ * }
89845
+ * },
89846
+ * "automatic": {
89847
+ * "month": "2026-10",
89848
+ * "count": 240,
89849
+ * "total_clp": 61200000,
89850
+ * "unreviewed_count": 31,
89851
+ * "by_actor": {
89852
+ * "rule": 150,
89853
+ * "match": 72,
89854
+ * "ai": 18
89855
+ * },
89856
+ * "recent": [
89857
+ * {
89858
+ * "kind": "link",
89859
+ * "id": "0190a3c2-5d1e-7b6a-9f20-4c1d2e3f6701",
89860
+ * "actor": "match",
89861
+ * "label": "Pago de la factura 4388 de Laboratorio Andes SpA",
89862
+ * "day": "2026-10-29",
89863
+ * "amount_clp": 1240000,
89864
+ * "applied_at": "2026-10-29T14:10:00.000Z",
89865
+ * "movement": {
89866
+ * "id": "0190a3c2-5d1e-7b6a-9f20-4c1d2e3f6801",
89867
+ * "day": "2026-10-29",
89868
+ * "amount_clp": 1240000,
89869
+ * "direction": "outbound",
89870
+ * "description": "Transferencia a Laboratorio Andes"
89871
+ * },
89872
+ * "document": null,
89873
+ * "target": "document",
89874
+ * "reasons": [
89875
+ * "rut",
89876
+ * "amount"
89877
+ * ],
89878
+ * "account": null,
89879
+ * "split": false,
89880
+ * "rule": null,
89881
+ * "reviewed_at": null,
89882
+ * "reviewed_by": null,
89883
+ * "group_name": "Laboratorio Andes SpA"
89884
+ * }
89885
+ * ]
89886
+ * },
89887
+ * "accounts": [
89888
+ * {
89889
+ * "id": "0190a3c2-5d1e-7b6a-9f20-4c1d2e3f6401",
89890
+ * "name": "Cuenta corriente",
89891
+ * "institution_name": "Banco de Chile",
89892
+ * "number_masked": "··4821",
89893
+ * "type": "cuenta_corriente",
89894
+ * "currency": "CLP",
89895
+ * "balance_clp": 3719083,
89896
+ * "balance_as_of": "2026-10-30T11:02:00.000Z",
89897
+ * "in_cash": true
89898
+ * },
89899
+ * {
89900
+ * "id": "0190a3c2-5d1e-7b6a-9f20-4c1d2e3f6402",
89901
+ * "name": "Ahorro",
89902
+ * "institution_name": "Banco de Chile",
89903
+ * "number_masked": "··0057",
89904
+ * "type": "cuenta_ahorro",
89905
+ * "currency": "CLP",
89906
+ * "balance_clp": 12000000,
89907
+ * "balance_as_of": "2026-10-30T11:02:00.000Z",
89908
+ * "in_cash": false
89909
+ * }
89910
+ * ]
89911
+ * }
89912
+ * }
89913
+ */
89914
+ "application/json": {
89915
+ data: components["schemas"]["FinanzasResumen"];
89916
+ };
89917
+ };
89918
+ };
89919
+ /** @description Validation error */
89920
+ 400: {
89921
+ headers: {
89922
+ [name: string]: unknown;
89923
+ };
89924
+ content: {
89925
+ "application/json": components["schemas"]["Error"];
89926
+ };
89927
+ };
89928
+ /** @description Unauthorized */
89929
+ 401: {
89930
+ headers: {
89931
+ [name: string]: unknown;
89932
+ };
89933
+ content: {
89934
+ "application/json": components["schemas"]["Error"];
89935
+ };
89936
+ };
89937
+ /** @description Forbidden */
89938
+ 403: {
89939
+ headers: {
89940
+ [name: string]: unknown;
89941
+ };
89942
+ content: {
89943
+ "application/json": components["schemas"]["Error"];
89944
+ };
89945
+ };
89946
+ /** @description Not found */
89947
+ 404: {
89948
+ headers: {
89949
+ [name: string]: unknown;
89950
+ };
89951
+ content: {
89952
+ "application/json": components["schemas"]["Error"];
89953
+ };
89954
+ };
89955
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
89956
+ 409: {
89957
+ headers: {
89958
+ [name: string]: unknown;
89959
+ };
89960
+ content: {
89961
+ "application/json": components["schemas"]["Error"];
89962
+ };
89963
+ };
89964
+ /** @description Rate limited */
89965
+ 429: {
89966
+ headers: {
89967
+ [name: string]: unknown;
89968
+ };
89969
+ content: {
89970
+ "application/json": components["schemas"]["Error"];
89971
+ };
89972
+ };
89973
+ };
89974
+ };
89975
+ put?: never;
89976
+ post?: never;
89977
+ delete?: never;
89978
+ options?: never;
89979
+ head?: never;
89980
+ patch?: never;
89981
+ trace?: never;
89982
+ };
88480
89983
  "/finanzas/produccion": {
88481
89984
  parameters: {
88482
89985
  query?: never;
@@ -88746,29 +90249,483 @@ interface paths {
88746
90249
  patch?: never;
88747
90250
  trace?: never;
88748
90251
  };
88749
- "/finanzas/contador-export/manifest": {
90252
+ "/finanzas/contador-export/manifest": {
90253
+ parameters: {
90254
+ query?: never;
90255
+ header?: never;
90256
+ path?: never;
90257
+ cookie?: never;
90258
+ };
90259
+ /**
90260
+ * What the Contador package for a month holds
90261
+ * @description The same package as the download, without the bytes: the period, the zip name and each file (key, label, name, rows, size). Over MCP this is the read that generates and checks the package; the zip itself downloads over HTTPS. A caller without the patient register (the Contador) sees a patient as «Paciente A. P.» with no RUT; the libro de ventas keeps the patient RUT on facturas and on notas de crédito or débito that cite one, and boletas carry neither RUT nor name. Requires the `finanzas` add-on — without it every Finanzas operation answers `402 ENTITLEMENT_NOT_ACTIVE` (`details.required = ["finanzas"]`). Requires `finanzas:read`, `finanzas_reports:read` and `finanzas:export` (the Contador seat, owners and admins).
90262
+ */
90263
+ get: {
90264
+ parameters: {
90265
+ query?: {
90266
+ period?: string;
90267
+ };
90268
+ header?: never;
90269
+ path?: never;
90270
+ cookie?: never;
90271
+ };
90272
+ requestBody?: never;
90273
+ responses: {
90274
+ /** @description The manifest */
90275
+ 200: {
90276
+ headers: {
90277
+ [name: string]: unknown;
90278
+ };
90279
+ content: {
90280
+ /**
90281
+ * @example {
90282
+ * "data": {
90283
+ * "period": "2026-09",
90284
+ * "filename": "paquete-contador-2026-09.zip",
90285
+ * "files": [
90286
+ * {
90287
+ * "key": "libro_compras",
90288
+ * "label": "Libro de compras",
90289
+ * "filename": "01-libro-de-compras-2026-09.xlsx",
90290
+ * "rows": 84,
90291
+ * "size_bytes": 14210
90292
+ * },
90293
+ * {
90294
+ * "key": "libro_ventas",
90295
+ * "label": "Libro de ventas",
90296
+ * "filename": "02-libro-de-ventas-2026-09.xlsx",
90297
+ * "rows": 1312,
90298
+ * "size_bytes": 61904
90299
+ * },
90300
+ * {
90301
+ * "key": "honorarios",
90302
+ * "label": "Honorarios",
90303
+ * "filename": "03-honorarios-2026-09.xlsx",
90304
+ * "rows": 12,
90305
+ * "size_bytes": 7480
90306
+ * },
90307
+ * {
90308
+ * "key": "movimientos",
90309
+ * "label": "Movimientos por cuenta",
90310
+ * "filename": "04-movimientos-por-cuenta-2026-09.xlsx",
90311
+ * "rows": 640,
90312
+ * "size_bytes": 38112
90313
+ * },
90314
+ * {
90315
+ * "key": "clasificaciones",
90316
+ * "label": "Clasificaciones por cuenta",
90317
+ * "filename": "05-clasificaciones-por-cuenta-2026-09.xlsx",
90318
+ * "rows": 702,
90319
+ * "size_bytes": 40356
90320
+ * },
90321
+ * {
90322
+ * "key": "resultado",
90323
+ * "label": "Resultado",
90324
+ * "filename": "06-resultado-2026-09.xlsx",
90325
+ * "rows": 1398,
90326
+ * "size_bytes": 52018
90327
+ * },
90328
+ * {
90329
+ * "key": "ajustes",
90330
+ * "label": "Ajustes posteriores al cierre",
90331
+ * "filename": "07-ajustes-posteriores-al-cierre-2026-09.xlsx",
90332
+ * "rows": 3,
90333
+ * "size_bytes": 6920
90334
+ * }
90335
+ * ]
90336
+ * }
90337
+ * }
90338
+ */
90339
+ "application/json": {
90340
+ data: {
90341
+ /** @description The month, `YYYY-MM`. */
90342
+ period: string;
90343
+ /** @description The zip the download serves. */
90344
+ filename: string;
90345
+ files: {
90346
+ /** @enum {string} */
90347
+ key: "libro_compras" | "libro_ventas" | "honorarios" | "movimientos" | "clasificaciones" | "resultado" | "ajustes";
90348
+ label: string;
90349
+ /** @description The xlsx inside the zip. */
90350
+ filename: string;
90351
+ /** @description Rows of its «Detalle» sheet (documents, items) when it has one, else of its first sheet (movements, adjustments). */
90352
+ rows: number;
90353
+ size_bytes: number;
90354
+ }[];
90355
+ };
90356
+ };
90357
+ };
90358
+ };
90359
+ /** @description Validation error */
90360
+ 400: {
90361
+ headers: {
90362
+ [name: string]: unknown;
90363
+ };
90364
+ content: {
90365
+ "application/json": components["schemas"]["Error"];
90366
+ };
90367
+ };
90368
+ /** @description Unauthorized */
90369
+ 401: {
90370
+ headers: {
90371
+ [name: string]: unknown;
90372
+ };
90373
+ content: {
90374
+ "application/json": components["schemas"]["Error"];
90375
+ };
90376
+ };
90377
+ /** @description Forbidden */
90378
+ 403: {
90379
+ headers: {
90380
+ [name: string]: unknown;
90381
+ };
90382
+ content: {
90383
+ "application/json": components["schemas"]["Error"];
90384
+ };
90385
+ };
90386
+ /** @description Not found */
90387
+ 404: {
90388
+ headers: {
90389
+ [name: string]: unknown;
90390
+ };
90391
+ content: {
90392
+ "application/json": components["schemas"]["Error"];
90393
+ };
90394
+ };
90395
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
90396
+ 409: {
90397
+ headers: {
90398
+ [name: string]: unknown;
90399
+ };
90400
+ content: {
90401
+ "application/json": components["schemas"]["Error"];
90402
+ };
90403
+ };
90404
+ /** @description Rate limited */
90405
+ 429: {
90406
+ headers: {
90407
+ [name: string]: unknown;
90408
+ };
90409
+ content: {
90410
+ "application/json": components["schemas"]["Error"];
90411
+ };
90412
+ };
90413
+ };
90414
+ };
90415
+ put?: never;
90416
+ post?: never;
90417
+ delete?: never;
90418
+ options?: never;
90419
+ head?: never;
90420
+ patch?: never;
90421
+ trace?: never;
90422
+ };
90423
+ "/finanzas/ads-connections": {
90424
+ parameters: {
90425
+ query?: never;
90426
+ header?: never;
90427
+ path?: never;
90428
+ cookie?: never;
90429
+ };
90430
+ /**
90431
+ * Ad accounts reachable for Cargos de publicidad
90432
+ * @description Per platform (Meta Ads, Google Ads): the ad accounts connected to the workspace, their status, last sync and the charges synced and linked, from the last read of the ad data. Each platform says what happens without a connection; connecting is Integraciones › Meta Ads. A card movement whose descriptor names Google Ads (`GOOGLE *ADS<customer id>`) or Meta (`FACEBK *<ref>`, `META*…`, `META PLATFORMS…`) becomes a `manual_expense` document of Contraparte «Google Ads» / «Meta Platforms» (`GET /finanzas/documents?origin=ads`); a refund (money in) a nota de crédito. Vitrina links it when the ad data makes it plausible (Meta: the billing charge of the same amount, count for count in time order; Google and Meta without charge data: the account spend since its previous charge must cover the amount), shown in «Hecho por Vitrina» with the evidence; the rest waits in «Por resolver» (case kind `ads_charge`). Vitrina never holds a Meta or Google token. Requires the `finanzas` add-on — without it every Finanzas operation answers `402 ENTITLEMENT_NOT_ACTIVE` (`details.required = ["finanzas"]`). Requires `finanzas:read`.
90433
+ */
90434
+ get: {
90435
+ parameters: {
90436
+ query?: never;
90437
+ header?: never;
90438
+ path?: never;
90439
+ cookie?: never;
90440
+ };
90441
+ requestBody?: never;
90442
+ responses: {
90443
+ /** @description The connections */
90444
+ 200: {
90445
+ headers: {
90446
+ [name: string]: unknown;
90447
+ };
90448
+ content: {
90449
+ /**
90450
+ * @example {
90451
+ * "data": {
90452
+ * "profile": true,
90453
+ * "last_attempt_at": "2026-10-31T12:30:00.000Z",
90454
+ * "last_sync_at": "2026-10-31T12:30:00.000Z",
90455
+ * "last_error": null,
90456
+ * "platforms": [
90457
+ * {
90458
+ * "platform": "meta_ads",
90459
+ * "label": "Meta Ads",
90460
+ * "status": "connected",
90461
+ * "accounts": [
90462
+ * {
90463
+ * "platform": "meta_ads",
90464
+ * "ad_account_id": "act_969938652650502",
90465
+ * "account_label": "act_969938652650502",
90466
+ * "account_name": "connectmarketing-cl",
90467
+ * "currency": "CLP",
90468
+ * "timezone": "America/Santiago",
90469
+ * "connection_status": "connected",
90470
+ * "healthy": true,
90471
+ * "last_synced_at": "2026-10-31T06:00:58.984Z",
90472
+ * "charges_supported": true,
90473
+ * "charges_synced_at": "2026-10-31T12:26:04.120Z",
90474
+ * "charges_synced": 40,
90475
+ * "charges_linked": 38,
90476
+ * "spend_by_month": [
90477
+ * {
90478
+ * "month": "2026-10",
90479
+ * "spend_minor": 545869,
90480
+ * "currency": "CLP"
90481
+ * }
90482
+ * ]
90483
+ * }
90484
+ * ],
90485
+ * "without_connection": "Sin la conexión, los cargos de Meta quedan en Por resolver hasta que reenvíes el recibo.",
90486
+ * "connect_path": "/integraciones/meta-ads"
90487
+ * },
90488
+ * {
90489
+ * "platform": "google_ads",
90490
+ * "label": "Google Ads",
90491
+ * "status": "none",
90492
+ * "accounts": [],
90493
+ * "without_connection": "Sin la conexión, los cargos de Google Ads quedan en Por resolver hasta que reenvíes el recibo.",
90494
+ * "connect_path": "/integraciones/meta-ads"
90495
+ * }
90496
+ * ]
90497
+ * }
90498
+ * }
90499
+ */
90500
+ "application/json": {
90501
+ data: components["schemas"]["FinanzasAdsConnections"];
90502
+ };
90503
+ };
90504
+ };
90505
+ /** @description Validation error */
90506
+ 400: {
90507
+ headers: {
90508
+ [name: string]: unknown;
90509
+ };
90510
+ content: {
90511
+ "application/json": components["schemas"]["Error"];
90512
+ };
90513
+ };
90514
+ /** @description Unauthorized */
90515
+ 401: {
90516
+ headers: {
90517
+ [name: string]: unknown;
90518
+ };
90519
+ content: {
90520
+ "application/json": components["schemas"]["Error"];
90521
+ };
90522
+ };
90523
+ /** @description Forbidden */
90524
+ 403: {
90525
+ headers: {
90526
+ [name: string]: unknown;
90527
+ };
90528
+ content: {
90529
+ "application/json": components["schemas"]["Error"];
90530
+ };
90531
+ };
90532
+ /** @description Not found */
90533
+ 404: {
90534
+ headers: {
90535
+ [name: string]: unknown;
90536
+ };
90537
+ content: {
90538
+ "application/json": components["schemas"]["Error"];
90539
+ };
90540
+ };
90541
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
90542
+ 409: {
90543
+ headers: {
90544
+ [name: string]: unknown;
90545
+ };
90546
+ content: {
90547
+ "application/json": components["schemas"]["Error"];
90548
+ };
90549
+ };
90550
+ /** @description Rate limited */
90551
+ 429: {
90552
+ headers: {
90553
+ [name: string]: unknown;
90554
+ };
90555
+ content: {
90556
+ "application/json": components["schemas"]["Error"];
90557
+ };
90558
+ };
90559
+ };
90560
+ };
90561
+ put?: never;
90562
+ post?: never;
90563
+ delete?: never;
90564
+ options?: never;
90565
+ head?: never;
90566
+ patch?: never;
90567
+ trace?: never;
90568
+ };
90569
+ "/finanzas/ads-charges": {
90570
+ parameters: {
90571
+ query?: never;
90572
+ header?: never;
90573
+ path?: never;
90574
+ cookie?: never;
90575
+ };
90576
+ /**
90577
+ * Meta billing charges synced, with their link state
90578
+ * @description Every billing event (charge, refund, chargeback, decline, funding) of the workspace's Meta ad accounts whose day (account time zone) is in [from, to], oldest first, never deduplicated by amount. `linked` = matched to the ads document of a card movement. Amounts in the smallest unit of `currency`. Requires the `finanzas` add-on — without it every Finanzas operation answers `402 ENTITLEMENT_NOT_ACTIVE` (`details.required = ["finanzas"]`). Requires `finanzas:read`.
90579
+ */
90580
+ get: {
90581
+ parameters: {
90582
+ query?: {
90583
+ from?: string;
90584
+ to?: string;
90585
+ };
90586
+ header?: never;
90587
+ path?: never;
90588
+ cookie?: never;
90589
+ };
90590
+ requestBody?: never;
90591
+ responses: {
90592
+ /** @description The charges */
90593
+ 200: {
90594
+ headers: {
90595
+ [name: string]: unknown;
90596
+ };
90597
+ content: {
90598
+ /**
90599
+ * @example {
90600
+ * "data": {
90601
+ * "from": "2026-10-22",
90602
+ * "to": "2026-10-22",
90603
+ * "items": [
90604
+ * {
90605
+ * "id": "0193a1b2-0000-7000-8000-000000000001",
90606
+ * "platform": "meta_ads",
90607
+ * "ad_account_id": "act_969938652650502",
90608
+ * "event_type": "ad_account_billing_charge",
90609
+ * "event_label": "cargo",
90610
+ * "event_time": "2026-10-22T12:14:00.000Z",
90611
+ * "local_date": "2026-10-22",
90612
+ * "meta_transaction_id": "29140315238986117-29184038214613815",
90613
+ * "amount_minor": 4211,
90614
+ * "currency": "CLP",
90615
+ * "link_state": "linked",
90616
+ * "document_id": "0193a1b2-0000-7000-8000-0000000000d1",
90617
+ * "movement_id": "0193a1b2-0000-7000-8000-0000000000a1",
90618
+ * "linked_at": "2026-10-24T09:00:00.000Z"
90619
+ * }
90620
+ * ],
90621
+ * "totals": {
90622
+ * "count": 1,
90623
+ * "linked": 1,
90624
+ * "unlinked": 0
90625
+ * }
90626
+ * }
90627
+ * }
90628
+ */
90629
+ "application/json": {
90630
+ data: components["schemas"]["FinanzasAdsChargesList"];
90631
+ };
90632
+ };
90633
+ };
90634
+ /** @description Validation error */
90635
+ 400: {
90636
+ headers: {
90637
+ [name: string]: unknown;
90638
+ };
90639
+ content: {
90640
+ "application/json": components["schemas"]["Error"];
90641
+ };
90642
+ };
90643
+ /** @description Unauthorized */
90644
+ 401: {
90645
+ headers: {
90646
+ [name: string]: unknown;
90647
+ };
90648
+ content: {
90649
+ "application/json": components["schemas"]["Error"];
90650
+ };
90651
+ };
90652
+ /** @description Forbidden */
90653
+ 403: {
90654
+ headers: {
90655
+ [name: string]: unknown;
90656
+ };
90657
+ content: {
90658
+ "application/json": components["schemas"]["Error"];
90659
+ };
90660
+ };
90661
+ /** @description Not found */
90662
+ 404: {
90663
+ headers: {
90664
+ [name: string]: unknown;
90665
+ };
90666
+ content: {
90667
+ "application/json": components["schemas"]["Error"];
90668
+ };
90669
+ };
90670
+ /** @description Conflict (incl. Idempotency-Key reuse with different body) */
90671
+ 409: {
90672
+ headers: {
90673
+ [name: string]: unknown;
90674
+ };
90675
+ content: {
90676
+ "application/json": components["schemas"]["Error"];
90677
+ };
90678
+ };
90679
+ /** @description Rate limited */
90680
+ 429: {
90681
+ headers: {
90682
+ [name: string]: unknown;
90683
+ };
90684
+ content: {
90685
+ "application/json": components["schemas"]["Error"];
90686
+ };
90687
+ };
90688
+ };
90689
+ };
90690
+ put?: never;
90691
+ post?: never;
90692
+ delete?: never;
90693
+ options?: never;
90694
+ head?: never;
90695
+ patch?: never;
90696
+ trace?: never;
90697
+ };
90698
+ "/finanzas/ads-charges/sync": {
88750
90699
  parameters: {
88751
90700
  query?: never;
88752
90701
  header?: never;
88753
90702
  path?: never;
88754
90703
  cookie?: never;
88755
90704
  };
90705
+ get?: never;
90706
+ put?: never;
88756
90707
  /**
88757
- * What the Contador package for a month holds
88758
- * @description The same package as the download, without the bytes: the period, the zip name and each file (key, label, name, rows, size). Over MCP this is the read that generates and checks the package; the zip itself downloads over HTTPS. A caller without the patient register (the Contador) sees a patient as «Paciente A. P.» with no RUT; the libro de ventas keeps the patient RUT on facturas and on notas de crédito or débito that cite one, and boletas carry neither RUT nor name. Requires the `finanzas` add-on — without it every Finanzas operation answers `402 ENTITLEMENT_NOT_ACTIVE` (`details.required = ["finanzas"]`). Requires `finanzas:read`, `finanzas_reports:read` and `finanzas:export` (the Contador seat, owners and admins).
90708
+ * Read the ad data now and match the card charges
90709
+ * @description «Sincronizar ahora»: recognise new ad charges among the card movements, read the last 92 days of ad billing and spend, store the charges and link what the evidence supports; then the reconciliation engine and «Por resolver» follow. A failed read is recorded (`read = error`, shown in `GET /finanzas/ads-connections`) and the stored charges still decide what they can. A card movement whose descriptor names Google Ads (`GOOGLE *ADS<customer id>`) or Meta (`FACEBK *<ref>`, `META*…`, `META PLATFORMS…`) becomes a `manual_expense` document of Contraparte «Google Ads» / «Meta Platforms» (`GET /finanzas/documents?origin=ads`); a refund (money in) a nota de crédito. Vitrina links it when the ad data makes it plausible (Meta: the billing charge of the same amount, count for count in time order; Google and Meta without charge data: the account spend since its previous charge must cover the amount), shown in «Hecho por Vitrina» with the evidence; the rest waits in «Por resolver» (case kind `ads_charge`). Vitrina never holds a Meta or Google token. Requires the `finanzas` add-on — without it every Finanzas operation answers `402 ENTITLEMENT_NOT_ACTIVE` (`details.required = ["finanzas"]`). Requires `finanzas_admin:write`.
88759
90710
  */
88760
- get: {
90711
+ post: {
88761
90712
  parameters: {
88762
- query?: {
88763
- period?: string;
90713
+ query?: never;
90714
+ header?: {
90715
+ /** @description Replay-safe retries: resending the SAME key with the SAME body returns the original response (`X-Idempotent-Replay: 1`) instead of creating a second copy — safe to send whenever a response might not have arrived. The same key with a DIFFERENT body answers `409 IDEMPOTENCY_KEY_CONFLICT`; use a fresh key per operation. */
90716
+ "Idempotency-Key"?: string;
88764
90717
  };
88765
- header?: never;
88766
90718
  path?: never;
88767
90719
  cookie?: never;
88768
90720
  };
88769
- requestBody?: never;
90721
+ requestBody?: {
90722
+ content: {
90723
+ /** @example {} */
90724
+ "application/json": Record<string, never>;
90725
+ };
90726
+ };
88770
90727
  responses: {
88771
- /** @description The manifest */
90728
+ /** @description What the run did */
88772
90729
  200: {
88773
90730
  headers: {
88774
90731
  [name: string]: unknown;
@@ -88777,79 +90734,27 @@ interface paths {
88777
90734
  /**
88778
90735
  * @example {
88779
90736
  * "data": {
88780
- * "period": "2026-09",
88781
- * "filename": "paquete-contador-2026-09.zip",
88782
- * "files": [
88783
- * {
88784
- * "key": "libro_compras",
88785
- * "label": "Libro de compras",
88786
- * "filename": "01-libro-de-compras-2026-09.xlsx",
88787
- * "rows": 84,
88788
- * "size_bytes": 14210
88789
- * },
88790
- * {
88791
- * "key": "libro_ventas",
88792
- * "label": "Libro de ventas",
88793
- * "filename": "02-libro-de-ventas-2026-09.xlsx",
88794
- * "rows": 1312,
88795
- * "size_bytes": 61904
88796
- * },
88797
- * {
88798
- * "key": "honorarios",
88799
- * "label": "Honorarios",
88800
- * "filename": "03-honorarios-2026-09.xlsx",
88801
- * "rows": 12,
88802
- * "size_bytes": 7480
88803
- * },
88804
- * {
88805
- * "key": "movimientos",
88806
- * "label": "Movimientos por cuenta",
88807
- * "filename": "04-movimientos-por-cuenta-2026-09.xlsx",
88808
- * "rows": 640,
88809
- * "size_bytes": 38112
88810
- * },
88811
- * {
88812
- * "key": "clasificaciones",
88813
- * "label": "Clasificaciones por cuenta",
88814
- * "filename": "05-clasificaciones-por-cuenta-2026-09.xlsx",
88815
- * "rows": 702,
88816
- * "size_bytes": 40356
88817
- * },
88818
- * {
88819
- * "key": "resultado",
88820
- * "label": "Resultado",
88821
- * "filename": "06-resultado-2026-09.xlsx",
88822
- * "rows": 1398,
88823
- * "size_bytes": 52018
88824
- * },
88825
- * {
88826
- * "key": "ajustes",
88827
- * "label": "Ajustes posteriores al cierre",
88828
- * "filename": "07-ajustes-posteriores-al-cierre-2026-09.xlsx",
88829
- * "rows": 3,
88830
- * "size_bytes": 6920
88831
- * }
88832
- * ]
90737
+ * "skipped": false,
90738
+ * "read": "ok",
90739
+ * "accounts": 1,
90740
+ * "charges_new": 3,
90741
+ * "recognize": {
90742
+ * "recognized": 4,
90743
+ * "created": 4,
90744
+ * "receipt_first": 0
90745
+ * },
90746
+ * "match": {
90747
+ * "open": 4,
90748
+ * "linked": 3,
90749
+ * "unconfirmed": 1,
90750
+ * "no_connection": 0,
90751
+ * "pending": 0
90752
+ * }
88833
90753
  * }
88834
90754
  * }
88835
90755
  */
88836
90756
  "application/json": {
88837
- data: {
88838
- /** @description The month, `YYYY-MM`. */
88839
- period: string;
88840
- /** @description The zip the download serves. */
88841
- filename: string;
88842
- files: {
88843
- /** @enum {string} */
88844
- key: "libro_compras" | "libro_ventas" | "honorarios" | "movimientos" | "clasificaciones" | "resultado" | "ajustes";
88845
- label: string;
88846
- /** @description The xlsx inside the zip. */
88847
- filename: string;
88848
- /** @description Rows of its «Detalle» sheet (documents, items) when it has one, else of its first sheet (movements, adjustments). */
88849
- rows: number;
88850
- size_bytes: number;
88851
- }[];
88852
- };
90757
+ data: components["schemas"]["FinanzasAdsSyncResult"];
88853
90758
  };
88854
90759
  };
88855
90760
  };
@@ -88909,8 +90814,6 @@ interface paths {
88909
90814
  };
88910
90815
  };
88911
90816
  };
88912
- put?: never;
88913
- post?: never;
88914
90817
  delete?: never;
88915
90818
  options?: never;
88916
90819
  head?: never;
@@ -255025,6 +256928,8 @@ interface components {
255025
256928
  account_id?: string;
255026
256929
  template_name?: string;
255027
256930
  template_language?: string;
256931
+ /** @description The weekly Finanzas digest template (resumen_finanzas_semanal_v1), wired on approval. */
256932
+ digest_template_name?: string;
255028
256933
  };
255029
256934
  stock_alert?: {
255030
256935
  /** @description Lead stages that trigger the «Stock faltante» check when a lead moves into them. Empty turns it off. */
@@ -255370,6 +257275,8 @@ interface components {
255370
257275
  account_id?: string;
255371
257276
  template_name?: string;
255372
257277
  template_language?: string;
257278
+ /** @description The weekly Finanzas digest template (resumen_finanzas_semanal_v1), wired on approval. */
257279
+ digest_template_name?: string;
255373
257280
  };
255374
257281
  stock_alert?: {
255375
257282
  /** @description Lead stages that trigger the «Stock faltante» check when a lead moves into them. Empty turns it off. */
@@ -257174,6 +259081,38 @@ interface components {
257174
259081
  /** @enum {string} */
257175
259082
  state: "vigente" | "anulada";
257176
259083
  } | null;
259084
+ /** @description Finanzas 30: a document Vitrina made from a Meta / Google card charge (`origin = ads`); null on every other document. */
259085
+ ads?: {
259086
+ /** @enum {string} */
259087
+ platform: "meta_ads" | "google_ads";
259088
+ /** @enum {string} */
259089
+ kind: "charge" | "refund";
259090
+ /** Format: uuid */
259091
+ movement_id: string | null;
259092
+ /**
259093
+ * @description linked = Vitrina linked the movement (see evidence); unconfirmed / no_connection = waiting in «Por resolver»; pending = the ad data could not be read yet; new = not decided.
259094
+ * @enum {string}
259095
+ */
259096
+ verdict: "new" | "pending" | "linked" | "unconfirmed" | "no_connection";
259097
+ reason: string | null;
259098
+ ad_account_id: string | null;
259099
+ customer_id: string | null;
259100
+ /** @description Meta: the card statement reference (`FACEBK *<ref>`). */
259101
+ reference: string | null;
259102
+ /** @description Meta's «Transaction ID» of the charge, once linked. */
259103
+ meta_transaction_id: string | null;
259104
+ evidence: string | null;
259105
+ spend_window: {
259106
+ ad_account_id: string;
259107
+ from: string;
259108
+ to: string;
259109
+ spend_minor: number;
259110
+ currency: string;
259111
+ } | null;
259112
+ /** @description The card movement's original currency. */
259113
+ currency: string | null;
259114
+ amount_original: number | null;
259115
+ } | null;
257177
259116
  created_at: string;
257178
259117
  updated_at: string;
257179
259118
  };
@@ -258102,10 +260041,10 @@ interface components {
258102
260041
  items: {
258103
260042
  id: string;
258104
260043
  /**
258105
- * @description reconcile = movements ↔ documents; transfer = between own accounts; classify = to an account; missing_document = «Falta documento» (money out classified with no document); unknown = no proposal yet.
260044
+ * @description reconcile = movements ↔ documents; transfer = between own accounts; classify = to an account; missing_document = «Falta documento» (money out classified with no document); unknown = no proposal yet; ads_charge = a Meta / Google card charge Vitrina could not confirm («Cargo de publicidad sin confirmar» / «Sin conexión de publicidad», Finanzas 30): the proposal links each movement to its own ads document.
258106
260045
  * @enum {string}
258107
260046
  */
258108
- kind: "reconcile" | "transfer" | "classify" | "missing_document" | "unknown";
260047
+ kind: "reconcile" | "transfer" | "classify" | "missing_document" | "unknown" | "ads_charge";
258109
260048
  title: string;
258110
260049
  summary: string;
258111
260050
  contraparte: {
@@ -258132,16 +260071,17 @@ interface components {
258132
260071
  classify: number;
258133
260072
  missing_document: number;
258134
260073
  unknown: number;
260074
+ ads_charge: number;
258135
260075
  };
258136
260076
  };
258137
260077
  FinanzasCase: {
258138
260078
  id: string;
258139
260079
  key: string;
258140
260080
  /**
258141
- * @description reconcile = movements ↔ documents; transfer = between own accounts; classify = to an account; missing_document = «Falta documento» (money out classified with no document); unknown = no proposal yet.
260081
+ * @description reconcile = movements ↔ documents; transfer = between own accounts; classify = to an account; missing_document = «Falta documento» (money out classified with no document); unknown = no proposal yet; ads_charge = a Meta / Google card charge Vitrina could not confirm («Cargo de publicidad sin confirmar» / «Sin conexión de publicidad», Finanzas 30): the proposal links each movement to its own ads document.
258142
260082
  * @enum {string}
258143
260083
  */
258144
- kind: "reconcile" | "transfer" | "classify" | "missing_document" | "unknown";
260084
+ kind: "reconcile" | "transfer" | "classify" | "missing_document" | "unknown" | "ads_charge";
258145
260085
  /** @enum {string} */
258146
260086
  status: "open" | "resolved";
258147
260087
  /** @enum {string|null} */
@@ -258255,6 +260195,34 @@ interface components {
258255
260195
  type: "document" | "movement";
258256
260196
  id: string;
258257
260197
  }[];
260198
+ /** @description Finanzas 30, `ads_charge` cases only: the matcher's verdict per movement and the Meta charges / ad accounts that could be it. Amounts in the smallest unit of `currency`. */
260199
+ ads?: {
260200
+ /** @enum {string} */
260201
+ platform: "meta_ads" | "google_ads";
260202
+ /** @enum {string} */
260203
+ verdict: "unconfirmed" | "no_connection";
260204
+ items: {
260205
+ /** Format: uuid */
260206
+ movement_id: string;
260207
+ /** Format: uuid */
260208
+ document_id: string;
260209
+ /** @description no_charge | count_mismatch | customer_id_unknown | spend_does_not_cover | ambiguous | refund_unmatched | undone_by_person | no_connection */
260210
+ reason: string;
260211
+ customer_id: string | null;
260212
+ reference: string | null;
260213
+ candidates: {
260214
+ /** Format: uuid */
260215
+ charge_id: string;
260216
+ ad_account_id: string;
260217
+ meta_transaction_id: string | null;
260218
+ event_time: string;
260219
+ local_date: string;
260220
+ amount_minor: number;
260221
+ currency: string;
260222
+ }[];
260223
+ candidate_accounts: string[];
260224
+ }[];
260225
+ } | null;
258258
260226
  opened_at: string;
258259
260227
  computed_at: string;
258260
260228
  };
@@ -258313,6 +260281,8 @@ interface components {
258313
260281
  /** @enum {string|null} */
258314
260282
  target: "document" | "payment" | "transfer" | "third_party" | "cash_deposit" | null;
258315
260283
  reasons: string[];
260284
+ /** @description Links Vitrina made from ad data (Finanzas 30, reasons include `ads_charge`): the evidence in one Spanish line, e.g. «Meta Ads cobró $4.211 el 22 oct a las 09:14 (cuenta …)» or «Gasto del 22 al 24 oct: $47.824 en la cuenta … de Google Ads; el cargo lo cubre». Null otherwise. */
260285
+ evidence: string | null;
258316
260286
  account: {
258317
260287
  /** Format: uuid */
258318
260288
  id: string;
@@ -258445,8 +260415,16 @@ interface components {
258445
260415
  /** @description Automatic actions of the month nobody reviewed in «Hecho por Vitrina». The close confirms this number. */
258446
260416
  unreviewed_count: number;
258447
260417
  unclassified_count: number;
260418
+ /** @description Still to reconcile in the month: bank movements not fully matched plus income documents (boletas, facturas) issued in the month still «Por conciliar» (the same definition as Resultado). */
258448
260419
  unmatched_count: number;
260420
+ /** @description Bank movements of the month not fully matched. */
260421
+ unmatched_movements_count: number;
260422
+ /** @description Income documents issued in the month still «Por conciliar». */
260423
+ unmatched_documents_count: number;
260424
+ /** @description What those movements and documents still leave unmatched, whole CLP. */
258449
260425
  unmatched_pending_clp: number;
260426
+ unmatched_movements_pending_clp: number;
260427
+ unmatched_documents_pending_clp: number;
258450
260428
  };
258451
260429
  close: {
258452
260430
  unreviewed_count: number;
@@ -258479,6 +260457,11 @@ interface components {
258479
260457
  count: number;
258480
260458
  pending_clp: number;
258481
260459
  };
260460
+ /** @description Income documents still «Por conciliar» at the close (closes made after 2026-10-31). */
260461
+ unmatched_documents?: {
260462
+ count: number;
260463
+ pending_clp: number;
260464
+ };
258482
260465
  };
258483
260466
  } | null;
258484
260467
  changes_since_close: {
@@ -258970,10 +260953,10 @@ interface components {
258970
260953
  /** @description Stable item key: document:<uuid>, recurring:<uuid>:<YYYY-MM-DD>, retention:<YYYY-MM>, rescue:<uuid>, cuotas:<day>, appointments:<day>, cash_pending. */
258971
260954
  key: string;
258972
260955
  /**
258973
- * @description payable = a purchase, honorario or gasto by due date; receivable = a sale or issued honorario by due date; retention = the retención of honorarios received, due with the F29; recurring = a recurring item occurrence; cuotas = patient cuotas of the day; appointments = booked appointments with a price of the day; cash_pending = efectivo por depositar; rescue = a planned «Rescatar fondo».
260956
+ * @description payable = a purchase, honorario or gasto by due date; receivable = a sale or issued honorario by due date; retention = the retención of honorarios received, due with the F29; recurring = a recurring item occurrence; cuotas = patient cuotas of the day; appointments = booked appointments with a price of the day; cash_pending = efectivo por depositar: only payments made in cash, still to deposit, today; card_settlement = card payments a processor has not paid out yet, on their payout day (2 business days, Chile holidays skipped); a transfer with no bank match is not projected (it is a Por resolver case); rescue = a planned «Rescatar fondo».
258974
260957
  * @enum {string}
258975
260958
  */
258976
- source: "payable" | "receivable" | "retention" | "recurring" | "cuotas" | "appointments" | "cash_pending" | "rescue";
260959
+ source: "payable" | "receivable" | "retention" | "recurring" | "cuotas" | "appointments" | "cash_pending" | "card_settlement" | "rescue";
258977
260960
  /** @enum {string} */
258978
260961
  direction: "inflow" | "outflow";
258979
260962
  label: string;
@@ -259091,6 +261074,13 @@ interface components {
259091
261074
  receivables_clp: number;
259092
261075
  receivables_count: number;
259093
261076
  };
261077
+ /** @description What the typical weekday income stands on. `insufficient_history` = fewer than 4 weeks of bank history: no typical income is projected (every `typical_inflow_clp` is 0 and there is no band) and the page should say so. */
261078
+ typical_income: {
261079
+ /** @enum {string} */
261080
+ basis: "history" | "insufficient_history";
261081
+ /** @description Whole weeks of bank history behind the weekday band. */
261082
+ weeks: number;
261083
+ };
259094
261084
  band_basis: {
259095
261085
  from: string | null;
259096
261086
  to: string;
@@ -259157,6 +261147,12 @@ interface components {
259157
261147
  } | null;
259158
261148
  };
259159
261149
  };
261150
+ /** @description `lowest` is measured over today .. `to` (`horizon_days`, default 30: the page's window); `month_end` is the end of the current month. */
261151
+ horizon: {
261152
+ days: number;
261153
+ /** @description Last day of the window. */
261154
+ to: string;
261155
+ };
259160
261156
  };
259161
261157
  FinanzasCashFlowMoveResult: {
259162
261158
  dry_run: boolean;
@@ -259313,6 +261309,72 @@ interface components {
259313
261309
  };
259314
261310
  };
259315
261311
  FinanzasAlertList: components["schemas"]["FinanzasAlert"][];
261312
+ FinanzasDigestPreview: {
261313
+ /** @description Monday of this week (YYYY-MM-DD, workspace time). */
261314
+ week_start: string;
261315
+ /** @description This week's send moment: Monday 09:00 workspace time (ISO). */
261316
+ send_at: string;
261317
+ /** @description Next Monday's 09:00 workspace time (ISO). */
261318
+ next_send_at: string;
261319
+ /**
261320
+ * @description This week's digest: `pending` (not sent yet), `sent`, or `empty` (no finance data that Monday, nothing went out).
261321
+ * @enum {string}
261322
+ */
261323
+ status: "pending" | "sent" | "empty";
261324
+ sent_at: string | null;
261325
+ /** @description The workspace has finance data now; false = no digest would go out. */
261326
+ will_send: boolean;
261327
+ /** @description The caller's own channels: their notification preferences for `finanzas.weekly_digest` and, for WhatsApp, the admin's opt-in `finanzas_whatsapp` rail with an approved digest template. */
261328
+ channels: {
261329
+ email: boolean;
261330
+ whatsapp: boolean;
261331
+ };
261332
+ email: {
261333
+ subject: string;
261334
+ hero: {
261335
+ /** @description «Caja hoy» or «Te necesita». */
261336
+ label: string;
261337
+ /** @description THE big number, formatted. */
261338
+ value: string;
261339
+ caption: string | null;
261340
+ };
261341
+ /** @description The one problem (the only red line): the cash runs out within 30 days, or a bank needs reconnecting. Null when there is none. */
261342
+ problem: {
261343
+ text: string;
261344
+ link: {
261345
+ label: string;
261346
+ /** @description Workspace-relative screen (prefix `/w/<workspace>`). */
261347
+ path: string;
261348
+ };
261349
+ } | null;
261350
+ /** @description The rest: the month against the punto de equilibrio, the open cases, what Vitrina ordered. */
261351
+ lines: string[];
261352
+ primary: {
261353
+ label: string;
261354
+ /** @description Workspace-relative screen (prefix `/w/<workspace>`). */
261355
+ path: string;
261356
+ };
261357
+ secondary: {
261358
+ label: string;
261359
+ /** @description Workspace-relative screen (prefix `/w/<workspace>`). */
261360
+ path: string;
261361
+ };
261362
+ };
261363
+ /** @description The WhatsApp `{{resumen}}` for the caller. */
261364
+ whatsapp_text: string;
261365
+ /** @description The same figures as `GET /finanzas/resumen` (whole CLP). Cash and result are null without `finanzas_reports:read`. */
261366
+ figures: {
261367
+ reports_visible: boolean;
261368
+ cash_today_clp: number | null;
261369
+ month_end_clp: number | null;
261370
+ in_30_days_clp: number | null;
261371
+ runs_out_date: string | null;
261372
+ ingresos_clp: number | null;
261373
+ resultado_clp: number | null;
261374
+ equilibrio_clp: number | null;
261375
+ open_cases: number;
261376
+ };
261377
+ };
259316
261378
  FinanzasCostos: {
259317
261379
  from: string;
259318
261380
  to: string;
@@ -259460,6 +261522,153 @@ interface components {
259460
261522
  updated_by: string | null;
259461
261523
  updated_at: string | null;
259462
261524
  };
261525
+ FinanzasResumenCash: {
261526
+ /** @description «Caja hoy»: today’s balance of the operating accounts (savings apart) = the Flujo de caja opening. */
261527
+ today_clp: number;
261528
+ balance_as_of: string | null;
261529
+ accounts_count: number;
261530
+ /** @description Operating accounts with no known balance (not in the total). */
261531
+ unknown_count: number;
261532
+ savings_clp: number;
261533
+ /** @description Projected balance at the end of the month. */
261534
+ month_end: {
261535
+ date: string;
261536
+ balance_clp: number;
261537
+ band: {
261538
+ low_clp: number;
261539
+ high_clp: number;
261540
+ } | null;
261541
+ };
261542
+ /** @description Projected balance 30 days from today. */
261543
+ in_30_days: {
261544
+ date: string;
261545
+ balance_clp: number;
261546
+ band: {
261547
+ low_clp: number;
261548
+ high_clp: number;
261549
+ } | null;
261550
+ };
261551
+ lowest: components["schemas"]["FinanzasCashFlowLowest"] & unknown;
261552
+ /** @description Null when cash stays ≥ 0 for 30 days. */
261553
+ runs_out: {
261554
+ /** @description The first projected day under zero. */
261555
+ date: string;
261556
+ /** @description «Alcanza hasta el …»: the day before. */
261557
+ covered_until: string;
261558
+ balance_clp: number;
261559
+ cause: components["schemas"]["FinanzasCashFlowItem"];
261560
+ } | null;
261561
+ overdue: {
261562
+ payables_clp: number;
261563
+ payables_count: number;
261564
+ stale_payables_clp: number;
261565
+ stale_payables_count: number;
261566
+ receivables_clp: number;
261567
+ receivables_count: number;
261568
+ };
261569
+ /** @description The runway: one point per day, today … today + 30. */
261570
+ points: {
261571
+ date: string;
261572
+ balance_clp: number;
261573
+ band: {
261574
+ low_clp: number;
261575
+ high_clp: number;
261576
+ } | null;
261577
+ }[];
261578
+ } | null;
261579
+ FinanzasResumenResult: {
261580
+ month: string;
261581
+ label: string;
261582
+ proforma: boolean;
261583
+ /** @description Net, as the Resultado. */
261584
+ ingresos_clp: number;
261585
+ /** @description «¿Cuánto gasto?»: variables + fijos. */
261586
+ gastos_clp: number;
261587
+ variables_clp: number;
261588
+ fijos_clp: number;
261589
+ /** @description Part of `variables_clp`: «Egresos sin clasificar», shown apart. */
261590
+ sin_clasificar_clp: number;
261591
+ /** @description The month’s Resultado operacional. */
261592
+ resultado_clp: number;
261593
+ /** @description The break-even line: Costos y equilibrio’s punto de equilibrio of the last closed month (its headline). */
261594
+ equilibrio: {
261595
+ month: string;
261596
+ label: string;
261597
+ equilibrio_clp: number | null;
261598
+ /** @enum {string|null} */
261599
+ sin_calculo: "sin_ingresos" | "margen_no_positivo" | null;
261600
+ } | null;
261601
+ /** @description Percent, one decimal. */
261602
+ cobertura_pct: number | null;
261603
+ /** @description ingresos − equilibrio (negative: still short of it). */
261604
+ brecha_clp: number | null;
261605
+ } | null;
261606
+ FinanzasResumen: {
261607
+ /** @description Today (America/Santiago). */
261608
+ as_of: string;
261609
+ month: string;
261610
+ month_label: string;
261611
+ /** @enum {string} */
261612
+ currency: "CLP";
261613
+ /** @description False for a caller without `finanzas_reports:read` (the «Finanzas» staff permission): `cash` and `result` are null. */
261614
+ reports_visible: boolean;
261615
+ /** @description The newest successful bank / Mercado Pago sync. */
261616
+ synced_at: string | null;
261617
+ /** @description The one problem shown in red: cash running out within 30 days first, else a bank connection that needs a person. */
261618
+ problem: {
261619
+ /** @enum {string} */
261620
+ kind: "cash_runs_out";
261621
+ date: string;
261622
+ balance_clp: number;
261623
+ } | {
261624
+ /** @enum {string} */
261625
+ kind: "connection";
261626
+ connection_id: string;
261627
+ institution_name: string | null;
261628
+ /** @enum {string} */
261629
+ status: "ok" | "pending" | "stale" | "error" | "login_required" | "disconnected";
261630
+ } | null;
261631
+ cash: components["schemas"]["FinanzasResumenCash"];
261632
+ result: components["schemas"]["FinanzasResumenResult"];
261633
+ inbox: components["schemas"]["FinanzasCaseCount"] & {
261634
+ /** @description The previous month, for «Cerrar {mes}» when nothing is open. Null (no prompt) when that month is before the month the add-on became active and holds no bank movements or documents. */
261635
+ close: {
261636
+ month: string;
261637
+ label: string;
261638
+ /** @enum {string} */
261639
+ state: "open" | "ready_to_close" | "closed";
261640
+ open_cases: number;
261641
+ } | null;
261642
+ };
261643
+ automatic: {
261644
+ month: string;
261645
+ count: number;
261646
+ total_clp: number;
261647
+ unreviewed_count: number;
261648
+ by_actor: {
261649
+ rule: number;
261650
+ match: number;
261651
+ ai: number;
261652
+ };
261653
+ /** @description The newest 3 automatic actions of the month; undo through POST /finanzas/automatic-actions/{kind}/{id}/undo. */
261654
+ recent: (components["schemas"]["FinanzasAutomaticAction"] & {
261655
+ group_name: string;
261656
+ })[];
261657
+ };
261658
+ accounts: {
261659
+ id: string;
261660
+ name: string;
261661
+ institution_name: string | null;
261662
+ number_masked: string | null;
261663
+ type: string;
261664
+ /** @enum {string} */
261665
+ currency: "CLP" | "USD";
261666
+ balance_clp: number | null;
261667
+ balance_as_of: string | null;
261668
+ /** @description False for savings accounts (not in «Caja hoy»). */
261669
+ in_cash: boolean;
261670
+ }[];
261671
+ };
259463
261672
  FinanzasPuente: {
259464
261673
  from: string;
259465
261674
  to: string;
@@ -259563,6 +261772,110 @@ interface components {
259563
261772
  payments: number;
259564
261773
  }[];
259565
261774
  };
261775
+ FinanzasAdsConnections: {
261776
+ /** @description The workspace has its ad-data link (provisioned when it connects Meta Ads). */
261777
+ profile: boolean;
261778
+ last_attempt_at: string | null;
261779
+ last_sync_at: string | null;
261780
+ /** @description Spanish copy when the last read failed, else null. */
261781
+ last_error: string | null;
261782
+ platforms: {
261783
+ /** @enum {string} */
261784
+ platform: "meta_ads" | "google_ads";
261785
+ /** @example Meta Ads */
261786
+ label: string;
261787
+ /**
261788
+ * @description connected = at least one healthy account; expired = accounts, none healthy; none = no account.
261789
+ * @enum {string}
261790
+ */
261791
+ status: "connected" | "expired" | "none";
261792
+ accounts: {
261793
+ /** @enum {string} */
261794
+ platform: "meta_ads" | "google_ads" | "tiktok_ads";
261795
+ /**
261796
+ * @description The platform's own id: Meta `act_…`, Google the 10-digit customer id.
261797
+ * @example act_969938652650502
261798
+ */
261799
+ ad_account_id: string;
261800
+ /** @description Google: `123-456-7890`; Meta: the `act_…` id. */
261801
+ account_label: string;
261802
+ account_name: string | null;
261803
+ currency: string | null;
261804
+ timezone: string | null;
261805
+ /** @description connected | syncing | error | disconnected | reconnect_required | revoked */
261806
+ connection_status: string;
261807
+ /** @description connected or syncing. */
261808
+ healthy: boolean;
261809
+ last_synced_at: string | null;
261810
+ /** @description True only for Meta. */
261811
+ charges_supported: boolean;
261812
+ /** @description When Meta's activity log was last read in full; null = never. */
261813
+ charges_synced_at: string | null;
261814
+ charges_synced: number;
261815
+ charges_linked: number;
261816
+ /** @description Spend per month over the last read (92 days), smallest unit of `currency`. */
261817
+ spend_by_month: {
261818
+ /** @example 2026-10 */
261819
+ month: string;
261820
+ spend_minor: number;
261821
+ currency: string | null;
261822
+ }[];
261823
+ }[];
261824
+ without_connection: string;
261825
+ /** @description Where to connect: Integraciones › Meta Ads (no connect flow here). */
261826
+ connect_path: string;
261827
+ }[];
261828
+ };
261829
+ FinanzasAdsCharge: {
261830
+ id: string;
261831
+ /** @enum {string} */
261832
+ platform: "meta_ads" | "google_ads" | "tiktok_ads";
261833
+ ad_account_id: string;
261834
+ event_type: string;
261835
+ /** @description cargo | reembolso | contracargo | rechazo | fondos */
261836
+ event_label: string;
261837
+ event_time: string;
261838
+ local_date: string;
261839
+ /** @description Meta's «Transaction ID» (Billing & payments), unique per charge. */
261840
+ meta_transaction_id: string | null;
261841
+ /** @description Smallest unit of `currency` (CLP pesos, USD cents). Null when Meta stated none. */
261842
+ amount_minor: number | null;
261843
+ currency: string | null;
261844
+ /** @enum {string} */
261845
+ link_state: "linked" | "unlinked";
261846
+ document_id: string | null;
261847
+ movement_id: string | null;
261848
+ linked_at: string | null;
261849
+ };
261850
+ FinanzasAdsChargesList: {
261851
+ from: string;
261852
+ to: string;
261853
+ items: components["schemas"]["FinanzasAdsCharge"][];
261854
+ totals: {
261855
+ count: number;
261856
+ linked: number;
261857
+ unlinked: number;
261858
+ };
261859
+ };
261860
+ FinanzasAdsSyncResult: {
261861
+ skipped: boolean;
261862
+ /** @enum {string} */
261863
+ read: "ok" | "no_profile" | "error" | "skipped";
261864
+ accounts: number;
261865
+ charges_new: number;
261866
+ recognize: {
261867
+ recognized: number;
261868
+ created: number;
261869
+ receipt_first: number;
261870
+ };
261871
+ match: {
261872
+ open: number;
261873
+ linked: number;
261874
+ unconfirmed: number;
261875
+ no_connection: number;
261876
+ pending: number;
261877
+ };
261878
+ };
259566
261879
  ClinicImportedBalanceBudget: {
259567
261880
  /** Format: uuid */
259568
261881
  budget_id: string;