@pimia/sdk 0.2.0 → 0.3.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.
package/README.md CHANGED
@@ -92,6 +92,63 @@ if (meta.idempotentReplay) {
92
92
  }
93
93
  ```
94
94
 
95
+ ## Recibir webhooks
96
+
97
+ `verifyWebhook` comprueba la firma `PIMIA-WEBHOOK-v1` y te devuelve el evento
98
+ tipado. No reimplementes el HMAC:
99
+
100
+ ```ts
101
+ import express from 'express'
102
+ import { verifyWebhook, WebhookVerificationError } from '@pimia/sdk'
103
+
104
+ // ⚠️ express.raw(), NO express.json(): Pimia firma los bytes que envía, y
105
+ // parsear + volver a serializar rompe la firma sin que se vea por qué.
106
+ app.post('/pimia', express.raw({ type: 'application/json' }), async (req, res) => {
107
+ let hook
108
+
109
+ try {
110
+ hook = await verifyWebhook({
111
+ secret: process.env.PIMIA_WEBHOOK_SECRET,
112
+ headers: req.headers,
113
+ body: req.body,
114
+ })
115
+ } catch (error) {
116
+ return res.status(400).send((error as WebhookVerificationError).reason)
117
+ }
118
+
119
+ // Pimia reintenta: la misma entrega llega con el mismo `delivery`.
120
+ // Procesar cada uno una sola vez es todo el exactly-once que necesitas.
121
+ if (await yaProcesado(hook.delivery)) return res.sendStatus(200)
122
+
123
+ if (hook.known) {
124
+ switch (hook.event) {
125
+ case 'estimate.accepted':
126
+ await facturar(hook.payload.id) // payload tipado, sin castings
127
+ break
128
+ case 'invoice.paid':
129
+ await cobrar(hook.payload.id)
130
+ break
131
+ }
132
+ }
133
+
134
+ res.sendStatus(200) // responde rápido; el trabajo pesado, a una cola
135
+ })
136
+ ```
137
+
138
+ Los ocho eventos del catálogo (`approval.decided`, `invoice.received`,
139
+ `app.revoked`, `customer.created`, `customer.updated`, `invoice.created`,
140
+ `estimate.accepted`, `invoice.paid`) vienen tipados. Uno que este SDK todavía
141
+ no conozca **no es un error**: se verifica igual y llega con `known: false`.
142
+
143
+ Detalles que ahorran un rato:
144
+
145
+ - `secret` acepta una **lista** de secretos, para rotarlo sin ventana de caída.
146
+ - La ventana anti-replay son 300 s; ajústala con `toleranceSeconds`.
147
+ - Los errores traen un `reason` (`signature_mismatch`, `timestamp_out_of_window`,
148
+ `missing_headers`, `invalid_timestamp`, `invalid_json`) para tus métricas.
149
+ - `signWebhook()` firma un cuerpo como lo haría Pimia: úsalo en **tus tests**,
150
+ no en producción.
151
+
95
152
  ## Más
96
153
 
97
154
  Documentación completa, modelo mental (un tenant = una base URL = un token),
package/dist/api.d.ts CHANGED
@@ -121,54 +121,6 @@ export interface paths {
121
121
  patch?: never;
122
122
  trace?: never;
123
123
  };
124
- "/auth/login": {
125
- parameters: {
126
- query?: never;
127
- header?: never;
128
- path?: never;
129
- cookie?: never;
130
- };
131
- get?: never;
132
- put?: never;
133
- post: operations["auth.login"];
134
- delete?: never;
135
- options?: never;
136
- head?: never;
137
- patch?: never;
138
- trace?: never;
139
- };
140
- "/auth/logout": {
141
- parameters: {
142
- query?: never;
143
- header?: never;
144
- path?: never;
145
- cookie?: never;
146
- };
147
- get?: never;
148
- put?: never;
149
- post: operations["auth.logout"];
150
- delete?: never;
151
- options?: never;
152
- head?: never;
153
- patch?: never;
154
- trace?: never;
155
- };
156
- "/auth/check": {
157
- parameters: {
158
- query?: never;
159
- header?: never;
160
- path?: never;
161
- cookie?: never;
162
- };
163
- get: operations["auth.check"];
164
- put?: never;
165
- post?: never;
166
- delete?: never;
167
- options?: never;
168
- head?: never;
169
- patch?: never;
170
- trace?: never;
171
- };
172
124
  "/bank-accounts": {
173
125
  parameters: {
174
126
  query?: never;
@@ -278,7 +230,10 @@ export interface paths {
278
230
  };
279
231
  get?: never;
280
232
  put?: never;
281
- /** Handle the incoming request */
233
+ /**
234
+ * Handle the incoming request
235
+ * @description **No disponible para integradores.** Exige `settings:write`, que el Authorization Server de Pimia no emite: la acción la realiza el dueño desde su panel y un token de partner recibe `403`. Aparece en el contrato para que el hueco sea explícito, no para que se llame.
236
+ */
282
237
  post: operations["general.bulkExchangeRate"];
283
238
  delete?: never;
284
239
  options?: never;
@@ -498,7 +453,10 @@ export interface paths {
498
453
  /** Display a listing of the resource */
499
454
  get: operations["custom-fields.index"];
500
455
  put?: never;
501
- /** Store a newly created resource in storage */
456
+ /**
457
+ * Store a newly created resource in storage
458
+ * @description **No disponible para integradores.** Exige `settings:write`, que el Authorization Server de Pimia no emite: la acción la realiza el dueño desde su panel y un token de partner recibe `403`. Aparece en el contrato para que el hueco sea explícito, no para que se llame.
459
+ */
502
460
  post: operations["custom-fields.store"];
503
461
  delete?: never;
504
462
  options?: never;
@@ -515,10 +473,16 @@ export interface paths {
515
473
  };
516
474
  /** Display the specified resource */
517
475
  get: operations["custom-fields.show"];
518
- /** Update the specified resource in storage */
476
+ /**
477
+ * Update the specified resource in storage
478
+ * @description **No disponible para integradores.** Exige `settings:write`, que el Authorization Server de Pimia no emite: la acción la realiza el dueño desde su panel y un token de partner recibe `403`. Aparece en el contrato para que el hueco sea explícito, no para que se llame.
479
+ */
519
480
  put: operations["custom-fields.update"];
520
481
  post?: never;
521
- /** Remove the specified resource from storage */
482
+ /**
483
+ * Remove the specified resource from storage
484
+ * @description **No disponible para integradores.** Exige `settings:write`, que el Authorization Server de Pimia no emite: la acción la realiza el dueño desde su panel y un token de partner recibe `403`. Aparece en el contrato para que el hueco sea explícito, no para que se llame.
485
+ */
522
486
  delete: operations["custom-fields.destroy"];
523
487
  options?: never;
524
488
  head?: never;
@@ -906,23 +870,6 @@ export interface paths {
906
870
  trace?: never;
907
871
  };
908
872
  "/fiscal-quarters/toggle": {
909
- parameters: {
910
- query?: never;
911
- header?: never;
912
- path?: never;
913
- cookie?: never;
914
- };
915
- get?: never;
916
- put?: never;
917
- /** Toggle lock state for a quarter */
918
- post: operations["fiscalQuarter.toggle"];
919
- delete?: never;
920
- options?: never;
921
- head?: never;
922
- patch?: never;
923
- trace?: never;
924
- };
925
- "/auth/password/email": {
926
873
  parameters: {
927
874
  query?: never;
928
875
  header?: never;
@@ -932,14 +879,10 @@ export interface paths {
932
879
  get?: never;
933
880
  put?: never;
934
881
  /**
935
- * Igual que el `sendResetLinkEmail()` del trait, pero con la validación en
936
- * un FormRequest en vez de en su `validateEmail()` privado: ahí dentro el
937
- * generador del OpenAPI no la ve y este endpoint se publicaba sin cuerpo.
938
- * Mismas reglas (`required|email`)
939
- * @description La RESPUESTA, en cambio, ya no es la del trait: es SIEMPRE la misma,
940
- * exista el correo o no. Ver `respuestaNeutra()`.
882
+ * Toggle lock state for a quarter
883
+ * @description **No disponible para integradores.** Exige `reports:write`, que el Authorization Server de Pimia no emite: la acción la realiza el dueño desde su panel y un token de partner recibe `403`. Aparece en el contrato para que el hueco sea explícito, no para que se llame.
941
884
  */
942
- post: operations["forgotPassword.sendResetLinkEmail"];
885
+ post: operations["fiscalQuarter.toggle"];
943
886
  delete?: never;
944
887
  options?: never;
945
888
  head?: never;
@@ -1597,7 +1540,31 @@ export interface paths {
1597
1540
  path?: never;
1598
1541
  cookie?: never;
1599
1542
  };
1600
- /** Handle the incoming request */
1543
+ /**
1544
+ * Siguiente número de documento (orientativo, NO lo reserva)
1545
+ * @description Calcula al vuelo qué número le tocaría al próximo documento del tipo pedido, con el
1546
+ * formato de numeración configurado por la empresa. Es lo que el panel pinta en el
1547
+ * formulario antes de guardar.
1548
+ *
1549
+ * **No reserva nada y no es determinista.** No consume secuencia: dos llamadas
1550
+ * seguidas —o dos integradores a la vez— reciben el MISMO número, y quien guarde
1551
+ * primero se lo queda; el segundo se estrella contra el `unique` con un `422`.
1552
+ * El valor caduca en cuanto alguien crea un documento de ese tipo.
1553
+ *
1554
+ * **No lo necesitas para escribir, y usarlo para eso te perjudica.** Desde el
1555
+ * 2026-08-10 ninguna alta exige que el número lo pongas tú: `invoice_number`,
1556
+ * `estimate_number`, `payment_number` y `received_invoice_number` son opcionales y,
1557
+ * si no llegan, los asigna el servidor con este mismo formateador ya dentro de la
1558
+ * transacción que escribe. Pedir el número aquí para reenviarlo en el cuerpo solo
1559
+ * añade una carrera que el servidor no tiene, y de paso rompe la reproducibilidad
1560
+ * del cuerpo entre reintentos con `Idempotency-Key` (guía del integrador §7).
1561
+ * Su uso legítimo es previsualizar en una interfaz el número que le tocaría al
1562
+ * documento — para eso lo llama el panel.
1563
+ *
1564
+ * **Comprueba `success` antes de leer `nextNumber`.** Un fallo llega con `200` y el
1565
+ * sobre `{"success": false, "message": "..."}`; desestructurar `nextNumber` a ciegas
1566
+ * degrada en silencio a `null`.
1567
+ */
1601
1568
  get: operations["general.nextNumber"];
1602
1569
  put?: never;
1603
1570
  post?: never;
@@ -2195,23 +2162,6 @@ export interface paths {
2195
2162
  patch?: never;
2196
2163
  trace?: never;
2197
2164
  };
2198
- "/auth/reset/password": {
2199
- parameters: {
2200
- query?: never;
2201
- header?: never;
2202
- path?: never;
2203
- cookie?: never;
2204
- };
2205
- get?: never;
2206
- put?: never;
2207
- /** Reset the given user's password */
2208
- post: operations["resetPassword.reset"];
2209
- delete?: never;
2210
- options?: never;
2211
- head?: never;
2212
- patch?: never;
2213
- trace?: never;
2214
- };
2215
2165
  "/search": {
2216
2166
  parameters: {
2217
2167
  query?: never;
@@ -2538,7 +2488,9 @@ export interface paths {
2538
2488
  put?: never;
2539
2489
  /**
2540
2490
  * POST tasks/{task}/delegate — delega esta tarea CRM a su agente Pim
2541
- * @description Reusa el plano async `delegated_tasks` (el mismo que ya cierra el round-trip
2491
+ * @description **No disponible para integradores.** Exige `delegation:write`, que el Authorization Server de Pimia no emite: la acción la realiza el dueño desde su panel y un token de partner recibe `403`. Aparece en el contrato para que el hueco sea explícito, no para que se llame.
2492
+ *
2493
+ * Reusa el plano async `delegated_tasks` (el mismo que ya cierra el round-trip
2542
2494
  * delegar→agente→callback→sello): compone un context rico desde la tarea (título,
2543
2495
  * descripción y el lead/cliente/proyecto vinculado con sus datos), crea la
2544
2496
  * delegación, la entrega al Kanban del Copilot y la enlaza con la tarea.
@@ -3153,6 +3105,13 @@ export interface components {
3153
3105
  phone?: string | null;
3154
3106
  fax?: string | null;
3155
3107
  };
3108
+ /** @description Valores de campo personalizado del recurso. `id` es el de la definición, que se descubre en `GET /custom-fields` (catálogo `meta`, legible con cualquier token); las definiciones las crea el dueño del tenant desde su panel. Se devuelven en la clave `fields` del recurso. */
3109
+ customFields?: {
3110
+ /** @description Id de la definición del campo personalizado. */
3111
+ id: number;
3112
+ /** @description Valor a guardar. */
3113
+ value: string;
3114
+ }[];
3156
3115
  };
3157
3116
  /** CustomerResource */
3158
3117
  CustomerResource: {
@@ -3402,6 +3361,13 @@ export interface components {
3402
3361
  percent?: number | null;
3403
3362
  amount?: number | null;
3404
3363
  }[] | null;
3364
+ /** @description Valores de campo personalizado DE LA LÍNEA (definiciones con `model_type` `InvoiceItem` o `EstimateItem`). Se acepta también la clave `custom_fields`, la forma histórica del panel. */
3365
+ customFields?: {
3366
+ /** @description Id de la definición del campo personalizado. */
3367
+ id: number;
3368
+ /** @description Valor a guardar. */
3369
+ value: string;
3370
+ }[];
3405
3371
  }[];
3406
3372
  taxes?: {
3407
3373
  tax_type_id?: number | null;
@@ -3415,6 +3381,13 @@ export interface components {
3415
3381
  */
3416
3382
  tax_per_item?: string | null;
3417
3383
  tax_included?: boolean | null;
3384
+ /** @description Valores de campo personalizado del recurso. `id` es el de la definición, que se descubre en `GET /custom-fields` (catálogo `meta`, legible con cualquier token); las definiciones las crea el dueño del tenant desde su panel. Se devuelven en la clave `fields` del recurso. */
3385
+ customFields?: {
3386
+ /** @description Id de la definición del campo personalizado. */
3387
+ id: number;
3388
+ /** @description Valor a guardar. */
3389
+ value: string;
3390
+ }[];
3418
3391
  };
3419
3392
  /** ExpenseCategoryRequest */
3420
3393
  ExpenseCategoryRequest: {
@@ -3448,6 +3421,10 @@ export interface components {
3448
3421
  * @description Maximum file size: 20000 kilobytes.
3449
3422
  */
3450
3423
  attachment_receipt?: string | null;
3424
+ /** @description Valores de campo personalizado del recurso. `id` es el de la definición, que se descubre en `GET /custom-fields` (catálogo `meta`, legible con cualquier token); las definiciones las crea el dueño del tenant desde su panel. Se devuelven en la clave `fields` del recurso. En `multipart/form-data` viaja como cadena JSON: `[{"id":3,"value":"REF-42"}]`. */
3425
+ customFields?: string;
3426
+ /** @description Borra el recibo adjunto del gasto. Solo surte efecto en la actualización; en `multipart/form-data` viaja como `1` o `0`. */
3427
+ is_attachment_receipt_removed?: boolean | null;
3451
3428
  };
3452
3429
  /** ExpenseResource */
3453
3430
  ExpenseResource: {
@@ -3479,23 +3456,6 @@ export interface components {
3479
3456
  currency?: components["schemas"]["CurrencyResource"];
3480
3457
  payment_method?: components["schemas"]["PaymentMethodResource"];
3481
3458
  };
3482
- /**
3483
- * ForgotPasswordRequest
3484
- * @description Envío del enlace de restablecimiento (`POST /auth/password/email`).
3485
- *
3486
- * Mismas reglas que el `validateEmail()` del trait
3487
- * `Illuminate\Foundation\Auth\SendsPasswordResetEmails` (laravel/ui), palabra
3488
- * por palabra. Estaban ahí dentro y por eso el OpenAPI publicaba este endpoint
3489
- * sin cuerpo: el generador solo mira la acción del controlador, y la acción
3490
- * venía entera del trait.
3491
- */
3492
- ForgotPasswordRequest: {
3493
- /**
3494
- * Format: email
3495
- * @description Correo de la cuenta. La respuesta no distingue si existe o no.
3496
- */
3497
- email: string;
3498
- };
3499
3459
  /** InvestmentAssetResource */
3500
3460
  InvestmentAssetResource: {
3501
3461
  id: string;
@@ -3771,6 +3731,13 @@ export interface components {
3771
3731
  percent?: number | null;
3772
3732
  amount?: number | null;
3773
3733
  }[] | null;
3734
+ /** @description Valores de campo personalizado DE LA LÍNEA (definiciones con `model_type` `InvoiceItem` o `EstimateItem`). Se acepta también la clave `custom_fields`, la forma histórica del panel. */
3735
+ customFields?: {
3736
+ /** @description Id de la definición del campo personalizado. */
3737
+ id: number;
3738
+ /** @description Valor a guardar. */
3739
+ value: string;
3740
+ }[];
3774
3741
  }[];
3775
3742
  taxes?: {
3776
3743
  tax_type_id?: number | null;
@@ -3784,6 +3751,13 @@ export interface components {
3784
3751
  */
3785
3752
  tax_per_item?: string | null;
3786
3753
  tax_included?: boolean | null;
3754
+ /** @description Valores de campo personalizado del recurso. `id` es el de la definición, que se descubre en `GET /custom-fields` (catálogo `meta`, legible con cualquier token); las definiciones las crea el dueño del tenant desde su panel. Se devuelven en la clave `fields` del recurso. */
3755
+ customFields?: {
3756
+ /** @description Id de la definición del campo personalizado. */
3757
+ id: number;
3758
+ /** @description Valor a guardar. */
3759
+ value: string;
3760
+ }[];
3787
3761
  };
3788
3762
  /** ItemCategory */
3789
3763
  ItemCategory: string[];
@@ -3841,6 +3815,8 @@ export interface components {
3841
3815
  stock_alert_qty?: number | null;
3842
3816
  allow_sale_without_stock?: boolean | null;
3843
3817
  purchase_tax_type_id?: number | null;
3818
+ /** @description Existencias iniciales del artículo. En el alta se guarda 0 si no llega; en la actualización se conserva el valor que ya tenía. */
3819
+ opening_stock?: number | null;
3844
3820
  };
3845
3821
  /** LeadActivity */
3846
3822
  LeadActivity: string[];
@@ -3920,12 +3896,6 @@ export interface components {
3920
3896
  name: string;
3921
3897
  } | null;
3922
3898
  };
3923
- /** LoginRequest */
3924
- LoginRequest: {
3925
- username: string;
3926
- password: string;
3927
- device_name: string;
3928
- };
3929
3899
  /** Note */
3930
3900
  Note: {
3931
3901
  id: number;
@@ -3958,10 +3928,27 @@ export interface components {
3958
3928
  customer_id: string;
3959
3929
  exchange_rate?: string | null;
3960
3930
  amount: number;
3961
- payment_number: string;
3931
+ /**
3932
+ * @description Opcional en el alta: si no llega, lo genera el servidor con el mismo
3933
+ * SerialNumberFormatter que alimenta a GET /next-number?key=payment, que es
3934
+ * de donde lo saca el panel. Exigirlo obligaba a un cliente de la API a
3935
+ * replicar el formato de numeración de la empresa, y encima a congelar el
3936
+ * cuerpo entre reintentos: `next-number` no reserva nada, así que pedirlo
3937
+ * dos veces puede dar dos números distintos y el reintento con la misma
3938
+ * Idempotency-Key rebotaba con 422 por «cuerpo distinto».
3939
+ * En PUT sigue siendo obligatorio (más abajo): el pago ya tiene uno.
3940
+ */
3941
+ payment_number?: string | null;
3962
3942
  invoice_id?: string | null;
3963
3943
  payment_method_id?: string | null;
3964
3944
  notes?: string | null;
3945
+ /** @description Valores de campo personalizado del recurso. `id` es el de la definición, que se descubre en `GET /custom-fields` (catálogo `meta`, legible con cualquier token); las definiciones las crea el dueño del tenant desde su panel. Se devuelven en la clave `fields` del recurso. */
3946
+ customFields?: {
3947
+ /** @description Id de la definición del campo personalizado. */
3948
+ id: number;
3949
+ /** @description Valor a guardar. */
3950
+ value: string;
3951
+ }[];
3965
3952
  };
3966
3953
  /** PaymentResource */
3967
3954
  PaymentResource: {
@@ -4073,7 +4060,18 @@ export interface components {
4073
4060
  received_invoice_date: string;
4074
4061
  due_date?: string | null;
4075
4062
  supplier_id: string;
4076
- received_invoice_number: string;
4063
+ /**
4064
+ * @description Opcional en el alta: si no llega, lo genera el servidor con el mismo
4065
+ * SerialNumberFormatter que alimenta a GET /next-number?key=received_invoice,
4066
+ * que es de donde lo saca el panel. Es el número del LIBRO DE RECIBIDAS —el
4067
+ * del proveedor va en `reference_number`—, así que numerarlo es cosa nuestra,
4068
+ * no del cliente de la API: exigirlo le obligaba a replicar el formato de la
4069
+ * empresa y a congelar el cuerpo entre reintentos (`next-number` no reserva,
4070
+ * dos llamadas pueden dar números distintos y la misma Idempotency-Key
4071
+ * rebotaba con 422 por «cuerpo distinto»).
4072
+ * En PUT sigue siendo obligatorio (más abajo): la factura ya tiene uno.
4073
+ */
4074
+ received_invoice_number?: string | null;
4077
4075
  exchange_rate?: string | null;
4078
4076
  discount: number;
4079
4077
  discount_val: number;
@@ -4216,6 +4214,13 @@ export interface components {
4216
4214
  */
4217
4215
  tax_per_item?: string | null;
4218
4216
  tax_included?: boolean | null;
4217
+ /** @description Valores de campo personalizado del recurso. `id` es el de la definición, que se descubre en `GET /custom-fields` (catálogo `meta`, legible con cualquier token); las definiciones las crea el dueño del tenant desde su panel. Se devuelven en la clave `fields` del recurso. */
4218
+ customFields?: {
4219
+ /** @description Id de la definición del campo personalizado. */
4220
+ id: number;
4221
+ /** @description Valor a guardar. */
4222
+ value: string;
4223
+ }[];
4219
4224
  };
4220
4225
  /** RecurringInvoiceResource */
4221
4226
  RecurringInvoiceResource: {
@@ -4409,6 +4414,13 @@ export interface components {
4409
4414
  phone?: string | null;
4410
4415
  fax?: string | null;
4411
4416
  };
4417
+ /** @description Valores de campo personalizado del recurso. `id` es el de la definición, que se descubre en `GET /custom-fields` (catálogo `meta`, legible con cualquier token); las definiciones las crea el dueño del tenant desde su panel. Se devuelven en la clave `fields` del recurso. */
4418
+ customFields?: {
4419
+ /** @description Id de la definición del campo personalizado. */
4420
+ id: number;
4421
+ /** @description Valor a guardar. */
4422
+ value: string;
4423
+ }[];
4412
4424
  };
4413
4425
  /** SupplierResource */
4414
4426
  SupplierResource: {
@@ -5122,74 +5134,6 @@ export interface operations {
5122
5134
  };
5123
5135
  };
5124
5136
  };
5125
- "auth.login": {
5126
- parameters: {
5127
- query?: never;
5128
- header?: never;
5129
- path?: never;
5130
- cookie?: never;
5131
- };
5132
- requestBody: {
5133
- content: {
5134
- "application/json": components["schemas"]["LoginRequest"];
5135
- };
5136
- };
5137
- responses: {
5138
- 200: {
5139
- headers: {
5140
- [name: string]: unknown;
5141
- };
5142
- content: {
5143
- "application/json": {
5144
- /** @constant */
5145
- type: "Bearer";
5146
- token: string;
5147
- };
5148
- };
5149
- };
5150
- 422: components["responses"]["ValidationException"];
5151
- };
5152
- };
5153
- "auth.logout": {
5154
- parameters: {
5155
- query?: never;
5156
- header?: never;
5157
- path?: never;
5158
- cookie?: never;
5159
- };
5160
- requestBody?: never;
5161
- responses: {
5162
- 200: {
5163
- headers: {
5164
- [name: string]: unknown;
5165
- };
5166
- content: {
5167
- "application/json": {
5168
- success: boolean;
5169
- };
5170
- };
5171
- };
5172
- };
5173
- };
5174
- "auth.check": {
5175
- parameters: {
5176
- query?: never;
5177
- header?: never;
5178
- path?: never;
5179
- cookie?: never;
5180
- };
5181
- requestBody?: never;
5182
- responses: {
5183
- 200: {
5184
- headers: {
5185
- [name: string]: unknown;
5186
- };
5187
- content: {
5188
- "application/json": boolean;
5189
- };
5190
- };
5191
- };
5192
- };
5193
5137
  "bank-accounts.index": {
5194
5138
  parameters: {
5195
5139
  query?: never;
@@ -7174,35 +7118,6 @@ export interface operations {
7174
7118
  422: components["responses"]["ValidationException"];
7175
7119
  };
7176
7120
  };
7177
- "forgotPassword.sendResetLinkEmail": {
7178
- parameters: {
7179
- query?: never;
7180
- header?: never;
7181
- path?: never;
7182
- cookie?: never;
7183
- };
7184
- requestBody: {
7185
- content: {
7186
- "application/json": components["schemas"]["ForgotPasswordRequest"];
7187
- };
7188
- };
7189
- responses: {
7190
- 200: {
7191
- headers: {
7192
- [name: string]: unknown;
7193
- };
7194
- content: {
7195
- "application/json": {
7196
- /** @constant */
7197
- message: "Password reset email sent.";
7198
- /** @constant */
7199
- data: "passwords.sent";
7200
- };
7201
- };
7202
- };
7203
- 422: components["responses"]["ValidationException"];
7204
- };
7205
- };
7206
7121
  "exchangeRate.getActiveProvider": {
7207
7122
  parameters: {
7208
7123
  query?: never;
@@ -8934,9 +8849,17 @@ export interface operations {
8934
8849
  };
8935
8850
  "general.nextNumber": {
8936
8851
  parameters: {
8937
- query?: {
8938
- invoice_series_id?: string;
8939
- series_id?: string;
8852
+ query: {
8853
+ /** @description Tipo de documento cuyo número se calcula. Obligatorio: un valor fuera de la lista devuelve `success: false`. */
8854
+ key: "invoice" | "credit_note" | "estimate" | "payment" | "delivery_note" | "received_invoice";
8855
+ /** @description Serie de facturación a usar (solo `key=invoice`). Sin ella manda la serie por defecto de la empresa. `invoice_series_id` es su alias histórico y solo se mira si `series_id` no viene. */
8856
+ series_id?: number;
8857
+ /** @description Alias histórico de `series_id`. En clientes nuevos usa `series_id`. */
8858
+ invoice_series_id?: number;
8859
+ /** @description Id del documento que se está EDITANDO. Con él el cálculo reutiliza la secuencia que ese documento ya tiene en vez de proponer la siguiente; sin él siempre propone la siguiente. */
8860
+ model_id?: number;
8861
+ /** @description Id del cliente, para los formatos de numeración que llevan su serie o su contador (`{{CUSTOMER_SERIES}}`, `{{CUSTOMER_SEQUENCE}}`). Irrelevante en el resto de formatos. */
8862
+ userId?: number;
8940
8863
  };
8941
8864
  header?: never;
8942
8865
  path?: never;
@@ -8944,12 +8867,18 @@ export interface operations {
8944
8867
  };
8945
8868
  requestBody?: never;
8946
8869
  responses: {
8870
+ /** @description Siempre `200`, también cuando falla: el discriminante es `success`. `nextNumber` es el número propuesto (`null` si `success` es `false`) e `isUsed` dice si la empresa ya tiene algún documento de ese tipo — el panel lo usa para saber si el formato de numeración todavía se puede cambiar. */
8947
8871
  200: {
8948
8872
  headers: {
8949
8873
  [name: string]: unknown;
8950
8874
  };
8951
8875
  content: {
8952
- "application/json": Record<string, never>;
8876
+ "application/json": {
8877
+ success: boolean;
8878
+ nextNumber: string | null;
8879
+ isUsed: boolean;
8880
+ message?: string;
8881
+ };
8953
8882
  };
8954
8883
  };
8955
8884
  };
@@ -10292,39 +10221,6 @@ export interface operations {
10292
10221
  };
10293
10222
  };
10294
10223
  };
10295
- "resetPassword.reset": {
10296
- parameters: {
10297
- query?: never;
10298
- header?: never;
10299
- path?: never;
10300
- cookie?: never;
10301
- };
10302
- requestBody: {
10303
- content: {
10304
- "application/json": {
10305
- token: string;
10306
- /** Format: email */
10307
- email: string;
10308
- password: string;
10309
- password_confirmation: string;
10310
- };
10311
- };
10312
- };
10313
- responses: {
10314
- 200: {
10315
- headers: {
10316
- [name: string]: unknown;
10317
- };
10318
- content: {
10319
- "application/json": {
10320
- /** @constant */
10321
- message: "Password reset successfully.";
10322
- } | Record<string, never>;
10323
- };
10324
- };
10325
- 422: components["responses"]["ValidationException"];
10326
- };
10327
- };
10328
10224
  "general.search": {
10329
10225
  parameters: {
10330
10226
  query?: never;