@pimia/sdk 0.20.0 → 0.27.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 +80 -0
- package/dist/api.d.ts +1020 -116
- package/dist/central-api.d.ts +1928 -0
- package/dist/central-api.js +9 -0
- package/dist/central.d.ts +607 -0
- package/dist/central.js +257 -0
- package/dist/client.d.ts +261 -1
- package/dist/client.js +212 -2
- package/dist/errors.d.ts +11 -0
- package/dist/errors.js +24 -0
- package/dist/index.d.ts +23 -3
- package/dist/index.js +21 -2
- package/dist/tokens.d.ts +45 -0
- package/dist/tokens.js +53 -0
- package/package.json +5 -1
package/dist/api.d.ts
CHANGED
|
@@ -301,6 +301,195 @@ export interface paths {
|
|
|
301
301
|
patch?: never;
|
|
302
302
|
trace?: never;
|
|
303
303
|
};
|
|
304
|
+
"/apps": {
|
|
305
|
+
parameters: {
|
|
306
|
+
query?: never;
|
|
307
|
+
header?: never;
|
|
308
|
+
path?: never;
|
|
309
|
+
cookie?: never;
|
|
310
|
+
};
|
|
311
|
+
/**
|
|
312
|
+
* El catálogo de integraciones con el estado de cada una EN ESTA EMPRESA
|
|
313
|
+
* @description **Reservada al panel de Pimia.** Exige `apps:read`, que el Authorization Server emite SOLO al client de primera parte: un client de integrador no puede pedir ese scope —se le rechaza en el registro y no se le anuncia— y con cualquier otro token la llamada recibe `403`. Está en el contrato porque es el panel web de Pimia quien la consume, y sus tipos salen de aquí.
|
|
314
|
+
*
|
|
315
|
+
* `status` distingue tres cosas y no dos: `not_installed` (no hay fila),
|
|
316
|
+
* `installed` y `disabled` (la hubo y se apagó, con su config a salvo).
|
|
317
|
+
*
|
|
318
|
+
* `authorization` dice si el grant que sostiene la instalación sigue vivo.
|
|
319
|
+
* Hasta #699 nadie lo enlaza, así que hoy es `null` en todas; la forma está
|
|
320
|
+
* para que la pantalla no cambie cuando deje de serlo.
|
|
321
|
+
*
|
|
322
|
+
* ⚠️ `price_cents` va en subunidades y SIN formatear: formatearlo aquí
|
|
323
|
+
* clavaría el euro en un quinto sitio (#517), y el precio de una app es
|
|
324
|
+
* suyo. Quien lo pinte ya sabe en qué moneda cobra.
|
|
325
|
+
*/
|
|
326
|
+
get: operations["apps.index"];
|
|
327
|
+
put?: never;
|
|
328
|
+
post?: never;
|
|
329
|
+
delete?: never;
|
|
330
|
+
options?: never;
|
|
331
|
+
head?: never;
|
|
332
|
+
patch?: never;
|
|
333
|
+
trace?: never;
|
|
334
|
+
};
|
|
335
|
+
"/apps/{slug}": {
|
|
336
|
+
parameters: {
|
|
337
|
+
query?: never;
|
|
338
|
+
header?: never;
|
|
339
|
+
path?: never;
|
|
340
|
+
cookie?: never;
|
|
341
|
+
};
|
|
342
|
+
/**
|
|
343
|
+
* La ficha de una integración: manifiesto, estado y su configuración
|
|
344
|
+
* ENMASCARADA (un secreto sale como si existe y sus últimos cuatro, nunca
|
|
345
|
+
* entero — ver {@see AppRegistry})
|
|
346
|
+
* @description **Reservada al panel de Pimia.** Exige `apps:read`, que el Authorization Server emite SOLO al client de primera parte: un client de integrador no puede pedir ese scope —se le rechaza en el registro y no se le anuncia— y con cualquier otro token la llamada recibe `403`. Está en el contrato porque es el panel web de Pimia quien la consume, y sus tipos salen de aquí.
|
|
347
|
+
*/
|
|
348
|
+
get: operations["apps.show"];
|
|
349
|
+
put?: never;
|
|
350
|
+
post?: never;
|
|
351
|
+
delete?: never;
|
|
352
|
+
options?: never;
|
|
353
|
+
head?: never;
|
|
354
|
+
patch?: never;
|
|
355
|
+
trace?: never;
|
|
356
|
+
};
|
|
357
|
+
"/apps/{slug}/install": {
|
|
358
|
+
parameters: {
|
|
359
|
+
query?: never;
|
|
360
|
+
header?: never;
|
|
361
|
+
path?: never;
|
|
362
|
+
cookie?: never;
|
|
363
|
+
};
|
|
364
|
+
get?: never;
|
|
365
|
+
put?: never;
|
|
366
|
+
/**
|
|
367
|
+
* Instalar la integración en esta empresa: la ceremonia completa
|
|
368
|
+
* @description **Reservada al panel de Pimia.** Exige `apps:write`, que el Authorization Server emite SOLO al client de primera parte: un client de integrador no puede pedir ese scope —se le rechaza en el registro y no se le anuncia— y con cualquier otro token la llamada recibe `403`. Está en el contrato porque es el panel web de Pimia quien la consume, y sus tipos salen de aquí.
|
|
369
|
+
*
|
|
370
|
+
* Enlaza el grant OAuth de quien instala —el patrón Slack: la app se
|
|
371
|
+
* instala con el token de quien la instaló, y si esa persona se va, la
|
|
372
|
+
* empresa reinstala— y registra los endpoints de webhook que declara el
|
|
373
|
+
* manifiesto, con el `client_id` de la app y esta company. La app puede
|
|
374
|
+
* devolver en su callback la URL de entrega (`webhook_url`), que manda
|
|
375
|
+
* sobre la del manifiesto.
|
|
376
|
+
*
|
|
377
|
+
* `webhook_secret` viene SOLO cuando se acaba de crear el endpoint: es lo
|
|
378
|
+
* que la app necesita para verificar la firma HMAC, y no se vuelve a
|
|
379
|
+
* enseñar (ni se rota en un reintento, que dejaría a la app verificando con
|
|
380
|
+
* uno viejo).
|
|
381
|
+
*
|
|
382
|
+
* Idempotente: si ya estaba instalada responde 200 sin reescribir
|
|
383
|
+
* `installed_at` —el día que #702 cobre, volver a pulsar no puede volver a
|
|
384
|
+
* cobrar— pero sí reintenta los enganches que falten. Si estaba apagada, la
|
|
385
|
+
* reenciende conservando su config.
|
|
386
|
+
*
|
|
387
|
+
* ⚠️ Desde el #710 puede responder **409 `app_retired`**: el superadmin
|
|
388
|
+
* retiró la app del catálogo. No es un 404 —la integración existe y quien la
|
|
389
|
+
* tenga puesta la sigue viendo y la puede desinstalar—; lo que ya no se
|
|
390
|
+
* puede es darla de alta. Quien lo pinte tiene que clasificar por el `error`
|
|
391
|
+
* del cuerpo, no por el status.
|
|
392
|
+
*/
|
|
393
|
+
post: operations["apps.install"];
|
|
394
|
+
/**
|
|
395
|
+
* Desinstalar: un botón, tres efectos
|
|
396
|
+
* @description **Reservada al panel de Pimia.** Exige `apps:write`, que el Authorization Server emite SOLO al client de primera parte: un client de integrador no puede pedir ese scope —se le rechaza en el registro y no se le anuncia— y con cualquier otro token la llamada recibe `403`. Está en el contrato porque es el panel web de Pimia quien la consume, y sus tipos salen de aquí.
|
|
397
|
+
*
|
|
398
|
+
* Revoca el grant que la sostenía (cascada de `TokenLifecycle`: sella el
|
|
399
|
+
* grant y sus refresh, borra los PAT de ese client en el esquema del
|
|
400
|
+
* tenant y emite `app.revoked` una sola vez), borra los endpoints de
|
|
401
|
+
* webhook de esta app en esta company, y apaga la fila.
|
|
402
|
+
*
|
|
403
|
+
* ⚠️ `billing.released` solo es `true` cuando de verdad había una partida
|
|
404
|
+
* que retirar, y **solo entonces `paid_until` significa algo** (#715). Si la
|
|
405
|
+
* app se cobra hoy pero esta suscripción nunca tuvo su partida —la
|
|
406
|
+
* instalación es anterior al precio, o la suscripción ya estaba cancelada—
|
|
407
|
+
* viene `nothing_to_release`. Quien pinte la frase no puede afirmar un mes
|
|
408
|
+
* pagado sin mirar cuál de las dos es.
|
|
409
|
+
*
|
|
410
|
+
* ⛔ Y hay un tercer «no se dio de baja» que **no se puede callar**:
|
|
411
|
+
* `release_failed`. Ahí la partida existía y Stripe no dejó quitarla, así
|
|
412
|
+
* que la integración queda desinstalada y **la suscripción la sigue
|
|
413
|
+
* cobrando** hasta que el reconciliador la cace. Callarlo es peor que
|
|
414
|
+
* equivocarse de frase: la empresa creería que dejó de pagar algo que se le
|
|
415
|
+
* sigue cobrando.
|
|
416
|
+
*
|
|
417
|
+
* La fila no se borra: «desinstalada» es un estado consultable, no la
|
|
418
|
+
* ausencia de información, y volver a instalar sale barato. La config se
|
|
419
|
+
* CONSERVA salvo que el manifiesto declare lo contrario, y la respuesta lo
|
|
420
|
+
* dice en `config_kept` — desinstalar por error no debe perder lo
|
|
421
|
+
* configurado.
|
|
422
|
+
*/
|
|
423
|
+
delete: operations["apps.uninstall"];
|
|
424
|
+
options?: never;
|
|
425
|
+
head?: never;
|
|
426
|
+
patch?: never;
|
|
427
|
+
trace?: never;
|
|
428
|
+
};
|
|
429
|
+
"/apps/{slug}/config": {
|
|
430
|
+
parameters: {
|
|
431
|
+
query?: never;
|
|
432
|
+
header?: never;
|
|
433
|
+
path?: never;
|
|
434
|
+
cookie?: never;
|
|
435
|
+
};
|
|
436
|
+
/**
|
|
437
|
+
* La configuración de la integración, enmascarada
|
|
438
|
+
* @description **Reservada al panel de Pimia.** Exige `apps:read`, que el Authorization Server emite SOLO al client de primera parte: un client de integrador no puede pedir ese scope —se le rechaza en el registro y no se le anuncia— y con cualquier otro token la llamada recibe `403`. Está en el contrato porque es el panel web de Pimia quien la consume, y sus tipos salen de aquí.
|
|
439
|
+
*/
|
|
440
|
+
get: operations["apps.config"];
|
|
441
|
+
/**
|
|
442
|
+
* Guardar configuración, validada contra el `config_schema` del manifiesto
|
|
443
|
+
* @description **Reservada al panel de Pimia.** Exige `apps:write`, que el Authorization Server emite SOLO al client de primera parte: un client de integrador no puede pedir ese scope —se le rechaza en el registro y no se le anuncia— y con cualquier otro token la llamada recibe `403`. Está en el contrato porque es el panel web de Pimia quien la consume, y sus tipos salen de aquí.
|
|
444
|
+
*
|
|
445
|
+
* Es un MERGE: lo que no viene, no se toca. Tiene que serlo porque quien
|
|
446
|
+
* edita desde una pantalla no tiene los secretos —solo ha visto sus últimos
|
|
447
|
+
* cuatro—, y un reemplazo los borraría cada vez que se cambia una URL. Para
|
|
448
|
+
* quitar un campo se manda `null`.
|
|
449
|
+
*
|
|
450
|
+
* Y se comprueba el resultado, no la entrada: si TRAS el merge faltara
|
|
451
|
+
* algún campo obligatorio, se rechaza con 422. Así la config no queda a
|
|
452
|
+
* medias sin que nadie lo note, y guardar solo un campo sigue valiendo.
|
|
453
|
+
*/
|
|
454
|
+
put: operations["apps.updateConfig"];
|
|
455
|
+
post?: never;
|
|
456
|
+
delete?: never;
|
|
457
|
+
options?: never;
|
|
458
|
+
head?: never;
|
|
459
|
+
patch?: never;
|
|
460
|
+
trace?: never;
|
|
461
|
+
};
|
|
462
|
+
"/apps/{slug}/credential": {
|
|
463
|
+
parameters: {
|
|
464
|
+
query?: never;
|
|
465
|
+
header?: never;
|
|
466
|
+
path?: never;
|
|
467
|
+
cookie?: never;
|
|
468
|
+
};
|
|
469
|
+
get?: never;
|
|
470
|
+
put?: never;
|
|
471
|
+
/**
|
|
472
|
+
* Acuñar o ROTAR la credencial de entrada de la app en esta empresa
|
|
473
|
+
* @description **Reservada al panel de Pimia.** Exige `apps:write`, que el Authorization Server emite SOLO al client de primera parte: un client de integrador no puede pedir ese scope —se le rechaza en el registro y no se le anuncia— y con cualquier otro token la llamada recibe `403`. Está en el contrato porque es el panel web de Pimia quien la consume, y sus tipos salen de aquí.
|
|
474
|
+
*
|
|
475
|
+
* Devuelve el secreto EN CLARO, y es la única vez que sale: en la base solo
|
|
476
|
+
* queda su hash. Rotar es sobrescribir —la anterior deja de valer en el
|
|
477
|
+
* acto, sin ventana de gracia—, que es lo que se espera de una rotación y lo
|
|
478
|
+
* que la hace útil como respuesta a una fuga.
|
|
479
|
+
*
|
|
480
|
+
* ⛔ Esto es acuñar una credencial, o sea justo lo que la decisión 4 de
|
|
481
|
+
* `docs/DECISIONES.md` deja fuera del mapa para los integradores. Sigue
|
|
482
|
+
* fuera: `apps:write` es `first_party_only` y además hace falta
|
|
483
|
+
* `manage company`. Lo que cambia es que la primera parte, con el dueño
|
|
484
|
+
* dentro, hace lo que hasta hoy hacía infra editando el `.env` del host.
|
|
485
|
+
*/
|
|
486
|
+
post: operations["apps.rotateCredential"];
|
|
487
|
+
delete?: never;
|
|
488
|
+
options?: never;
|
|
489
|
+
head?: never;
|
|
490
|
+
patch?: never;
|
|
491
|
+
trace?: never;
|
|
492
|
+
};
|
|
304
493
|
"/crm/assignable-users": {
|
|
305
494
|
parameters: {
|
|
306
495
|
query?: never;
|
|
@@ -1563,6 +1752,66 @@ export interface paths {
|
|
|
1563
1752
|
patch?: never;
|
|
1564
1753
|
trace?: never;
|
|
1565
1754
|
};
|
|
1755
|
+
"/desarrollador-link/status": {
|
|
1756
|
+
parameters: {
|
|
1757
|
+
query?: never;
|
|
1758
|
+
header?: never;
|
|
1759
|
+
path?: never;
|
|
1760
|
+
cookie?: never;
|
|
1761
|
+
};
|
|
1762
|
+
/**
|
|
1763
|
+
* GET — estado del vínculo de esta instancia
|
|
1764
|
+
* @description **Reservada al panel de Pimia.** Exige `admin:read`, que el Authorization Server emite SOLO al client de primera parte: un client de integrador no puede pedir ese scope —se le rechaza en el registro y no se le anuncia— y con cualquier otro token la llamada recibe `403`. Está en el contrato porque es el panel web de Pimia quien la consume, y sus tipos salen de aquí.
|
|
1765
|
+
*/
|
|
1766
|
+
get: operations["desarrolladorLink.status"];
|
|
1767
|
+
put?: never;
|
|
1768
|
+
post?: never;
|
|
1769
|
+
delete?: never;
|
|
1770
|
+
options?: never;
|
|
1771
|
+
head?: never;
|
|
1772
|
+
patch?: never;
|
|
1773
|
+
trace?: never;
|
|
1774
|
+
};
|
|
1775
|
+
"/desarrollador-link/request": {
|
|
1776
|
+
parameters: {
|
|
1777
|
+
query?: never;
|
|
1778
|
+
header?: never;
|
|
1779
|
+
path?: never;
|
|
1780
|
+
cookie?: never;
|
|
1781
|
+
};
|
|
1782
|
+
get?: never;
|
|
1783
|
+
put?: never;
|
|
1784
|
+
/**
|
|
1785
|
+
* POST — la instancia solicita vincularse con un código DEV-XXXX-XXXX
|
|
1786
|
+
* @description **Reservada al panel de Pimia.** Exige `admin:write`, que el Authorization Server emite SOLO al client de primera parte: un client de integrador no puede pedir ese scope —se le rechaza en el registro y no se le anuncia— y con cualquier otro token la llamada recibe `403`. Está en el contrato porque es el panel web de Pimia quien la consume, y sus tipos salen de aquí.
|
|
1787
|
+
*/
|
|
1788
|
+
post: operations["desarrolladorLink.request"];
|
|
1789
|
+
delete?: never;
|
|
1790
|
+
options?: never;
|
|
1791
|
+
head?: never;
|
|
1792
|
+
patch?: never;
|
|
1793
|
+
trace?: never;
|
|
1794
|
+
};
|
|
1795
|
+
"/desarrollador-link/revoke": {
|
|
1796
|
+
parameters: {
|
|
1797
|
+
query?: never;
|
|
1798
|
+
header?: never;
|
|
1799
|
+
path?: never;
|
|
1800
|
+
cookie?: never;
|
|
1801
|
+
};
|
|
1802
|
+
get?: never;
|
|
1803
|
+
put?: never;
|
|
1804
|
+
post?: never;
|
|
1805
|
+
/**
|
|
1806
|
+
* DELETE — la instancia rompe el vínculo. Siempre puede
|
|
1807
|
+
* @description **Reservada al panel de Pimia.** Exige `admin:write`, que el Authorization Server emite SOLO al client de primera parte: un client de integrador no puede pedir ese scope —se le rechaza en el registro y no se le anuncia— y con cualquier otro token la llamada recibe `403`. Está en el contrato porque es el panel web de Pimia quien la consume, y sus tipos salen de aquí.
|
|
1808
|
+
*/
|
|
1809
|
+
delete: operations["desarrolladorLink.revoke"];
|
|
1810
|
+
options?: never;
|
|
1811
|
+
head?: never;
|
|
1812
|
+
patch?: never;
|
|
1813
|
+
trace?: never;
|
|
1814
|
+
};
|
|
1566
1815
|
"/invoices/{invoice}/einvoice": {
|
|
1567
1816
|
parameters: {
|
|
1568
1817
|
query?: never;
|
|
@@ -5227,10 +5476,23 @@ export interface paths {
|
|
|
5227
5476
|
* @description **Reservada al panel de Pimia.** Exige `billing:read`, que el Authorization Server emite SOLO al client de primera parte: un client de integrador no puede pedir ese scope —se le rechaza en el registro y no se le anuncia— y con cualquier otro token la llamada recibe `403`. Está en el contrato porque es el panel web de Pimia quien la consume, y sus tipos salen de aquí.
|
|
5228
5477
|
*
|
|
5229
5478
|
* Sin los planes de canal (`Asesoría`, `Desarrollador`): esos los contrata
|
|
5230
|
-
* una gestoría o un desarrollador para su cartera, no una pyme. Con
|
|
5231
|
-
*
|
|
5232
|
-
*
|
|
5233
|
-
*
|
|
5479
|
+
* una gestoría o un desarrollador para su cartera, no una pyme. Con
|
|
5480
|
+
* INTEGRADOR —su licencia la paga un desarrollador, o entró por la app de
|
|
5481
|
+
* uno y el vínculo sigue vivo— la lista llega VACÍA y en su lugar va
|
|
5482
|
+
* `catalogo`: lo que ese integrador revende, a su precio y con su enlace
|
|
5483
|
+
* de contratación (regla 4 del punto 12; decisión de 👤 del 2026-09-06: el
|
|
5484
|
+
* cliente de un integrador no ve un precio de Pimia nunca, ni antes del
|
|
5485
|
+
* primer pago). `white_label` sigue diciendo el HECHO de que lo paga un
|
|
5486
|
+
* tercero; `catalogo` es `null` mientras el integrador no configure el
|
|
5487
|
+
* suyo. El corte va en el servidor.
|
|
5488
|
+
*
|
|
5489
|
+
* **Cada plan dice además qué módulos opcionales trae y cuáles costarían
|
|
5490
|
+
* aparte** (`optional_modules`), que es lo que la pantalla de contratación
|
|
5491
|
+
* necesita para ofrecer añadirlos al contratar: preguntárselo a
|
|
5492
|
+
* `GET /tenant-modules` sería preguntar por el plan de HOY, y quien está
|
|
5493
|
+
* eligiendo plan quiere saber lo del plan de MAÑANA. En un plan gratuito
|
|
5494
|
+
* no hay ni `included` ni `addon`: no incluye ninguno y no hay
|
|
5495
|
+
* suscripción a la que sumarlos (2026-09-04).
|
|
5234
5496
|
*/
|
|
5235
5497
|
get: operations["tenantBilling.plans"];
|
|
5236
5498
|
put?: never;
|
|
@@ -5262,6 +5524,33 @@ export interface paths {
|
|
|
5262
5524
|
* `usage.storage` es `null` cuando no se puede medir (esquema a medias) y
|
|
5263
5525
|
* `subscription.current_period_end` es `null` cuando Stripe no contesta:
|
|
5264
5526
|
* un dato que no consta se dice como tal, no se inventa un cero.
|
|
5527
|
+
*
|
|
5528
|
+
* **`addons` es lo que la suscripción paga en módulos añadidos** (desde
|
|
5529
|
+
* el 2026-09-04): cuántos, a cuánto, y la cuota mensual DE LISTA —plan
|
|
5530
|
+
* más añadidos **más integraciones**, sin prorrateos, cupones, impuestos
|
|
5531
|
+
* ni prueba: no es el próximo cargo— ya formateada. Existe porque el panel
|
|
5532
|
+
* enseñaba «Tu plan: Pimia, 12,00 € al mes» a una empresa que pagaba 14:
|
|
5533
|
+
* el precio del plan no es la cuota. La cantidad es la de la partida de
|
|
5534
|
+
* Stripe (copia local), no un recuento de filas —que contaría también los
|
|
5535
|
+
* heredados, que no se cobran—. `null` sin suscripción, y `null` en un
|
|
5536
|
+
* asiento PATROCINADO: su suscripción es la del canal, y la partida de ésa
|
|
5537
|
+
* la comparten todas sus instancias; la instancia no paga nada.
|
|
5538
|
+
*
|
|
5539
|
+
* **`apps` son las integraciones de pago, una a una** (desde el
|
|
5540
|
+
* 2026-09-05, #716), con su total propio. Salen de las partidas de la
|
|
5541
|
+
* suscripción, igual que la cantidad de módulos: ⛔ contar `company_apps`
|
|
5542
|
+
* diría de más en cuanto dos empresas de la instancia tuvieran la misma
|
|
5543
|
+
* —la segunda no vuelve a pagar—.
|
|
5544
|
+
*
|
|
5545
|
+
* ⛔ **Y el mismo defecto ha pasado DOS VECES en este campo.** `addons`
|
|
5546
|
+
* nació porque el total decía 12 y se pagaban 14 (el plan no es la cuota);
|
|
5547
|
+
* el 2026-09-05 decía 16 y se pagaban 25,90 (los módulos tampoco lo son).
|
|
5548
|
+
* Las dos veces el cálculo de los sumandos conocidos era correcto y lo que
|
|
5549
|
+
* faltaba era un sumando nuevo. La decisión que esto sirve —«una sola
|
|
5550
|
+
* cesta en el producto: el sitio donde la pyme ve lo que paga es uno»—
|
|
5551
|
+
* significa que **quien añada una partida de cobro tiene que sumarla en
|
|
5552
|
+
* `addonsPayload()`**, y que un total que no la incluya no es un total
|
|
5553
|
+
* incompleto: es una cifra falsa en la pantalla que la pyme lee.
|
|
5265
5554
|
*/
|
|
5266
5555
|
get: operations["tenantBilling.subscription"];
|
|
5267
5556
|
put?: never;
|
|
@@ -5296,9 +5585,19 @@ export interface paths {
|
|
|
5296
5585
|
* `true`, `checkout_url` es `null` y `plan` dice a cuál: el panel no tiene
|
|
5297
5586
|
* a dónde ir, solo refrescar.
|
|
5298
5587
|
*
|
|
5588
|
+
* **Los módulos opcionales se pueden comprar aquí mismo** (`modules`, lista
|
|
5589
|
+
* de slugs): la sesión de Stripe nace con dos partidas —el plan y «Módulo
|
|
5590
|
+
* adicional» con tantas unidades como módulos—, y al confirmarse el pago
|
|
5591
|
+
* quedan encendidos y marcados como añadidos. Se validan contra el plan que
|
|
5592
|
+
* se contrata, no contra el actual: lo que la instancia tiene hoy no dice
|
|
5593
|
+
* nada de lo que tendría mañana. Lo que ofrece cada plan lo publica
|
|
5594
|
+
* `GET /billing/plans` en `optional_modules`.
|
|
5595
|
+
*
|
|
5299
5596
|
* Errores, con su código en `error`: `white_label` (403), `no_payer` (409),
|
|
5300
5597
|
* `free_plan` y `channel_plan` (422), `tenant_already_subscribed` (422),
|
|
5301
|
-
* `
|
|
5598
|
+
* `invalid_addon_module` y `addon_included_in_plan` (422),
|
|
5599
|
+
* `stripe_resume_failed` (502), `stripe_price_missing` (503),
|
|
5600
|
+
* `stripe_addon_price_missing` (503).
|
|
5302
5601
|
*/
|
|
5303
5602
|
post: operations["tenantBilling.checkoutFromPanel"];
|
|
5304
5603
|
delete?: never;
|
|
@@ -5520,6 +5819,32 @@ export interface paths {
|
|
|
5520
5819
|
* publicaba, así que el panel web enseñaba un botón de «Desactivar» sobre
|
|
5521
5820
|
* `compliance-es` y otro de «Instalar» sobre `compliance-fr` en una empresa
|
|
5522
5821
|
* española (épica #677).
|
|
5822
|
+
*
|
|
5823
|
+
* **Los añadidos (2026-09-03).** Un opcional que el plan NO incluye se
|
|
5824
|
+
* puede añadir pagando, y la respuesta lo dice con cuatro campos:
|
|
5825
|
+
* `billing` (`core` no se vende, `included` lo trae el plan, `addon` se
|
|
5826
|
+
* paga aparte), `price_cents` y `price` (lo que costaría al mes; `null` si
|
|
5827
|
+
* no se vende), `purchasable` (si ESTA instancia puede comprarlo ahora:
|
|
5828
|
+
* tiene plan de pago y quien mira es su dueño) y `addon_active` (si ya lo
|
|
5829
|
+
* está pagando). Con `billing: addon` y `purchasable: false` la pantalla
|
|
5830
|
+
* lleva a contratar un plan, que es lo que el `402 subscription_required`
|
|
5831
|
+
* del alta también dice.
|
|
5832
|
+
*
|
|
5833
|
+
* `available_in_plan` se conserva y ahora es «incluido o añadible»: lo que
|
|
5834
|
+
* la instancia puede llegar a tener.
|
|
5835
|
+
*
|
|
5836
|
+
* **Con integrador (2026-09-06, regla 4 del punto 12)** los opcionales no
|
|
5837
|
+
* se compran a Pimia: los activa el integrador y los cobra él. Cada
|
|
5838
|
+
* opcional ofrecido lleva entonces `billing: channel`, `price` es el
|
|
5839
|
+
* precio MINORISTA de su catálogo (`null` si no lo revende), `purchasable`
|
|
5840
|
+
* es falso y `contract_url` es su enlace de contratación, con `tenant` e
|
|
5841
|
+
* `item` puestos.
|
|
5842
|
+
*
|
|
5843
|
+
* **`addon_ends_at`** (desde el 2026-09-04, noche): un añadido dado de
|
|
5844
|
+
* baja no se apaga, deja de RENOVARSE — sigue encendido hasta esa fecha
|
|
5845
|
+
* (el fin del periodo ya pagado) y ahí se apaga. Mientras tanto
|
|
5846
|
+
* `addon_active` sigue en `true` (este periodo está pagado) y volver a
|
|
5847
|
+
* activarlo no cobra: lo «mantiene». `null` en todo lo demás.
|
|
5523
5848
|
*/
|
|
5524
5849
|
get: operations["tenantModules.index"];
|
|
5525
5850
|
put?: never;
|
|
@@ -5543,9 +5868,30 @@ export interface paths {
|
|
|
5543
5868
|
* Instala un módulo en la instancia, y con él sus dependencias
|
|
5544
5869
|
* @description **Reservada al panel de Pimia.** Exige `admin:write`, que el Authorization Server emite SOLO al client de primera parte: un client de integrador no puede pedir ese scope —se le rechaza en el registro y no se le anuncia— y con cualquier otro token la llamada recibe `403`. Está en el contrato porque es el panel web de Pimia quien la consume, y sus tipos salen de aquí.
|
|
5545
5870
|
*
|
|
5546
|
-
* Un módulo que no existe, uno que el plan de la instancia no incluye
|
|
5547
|
-
* dependencia que no se puede satisfacer, salen
|
|
5548
|
-
* `message`.
|
|
5871
|
+
* Un módulo que no existe, uno que el plan de la instancia no incluye y no
|
|
5872
|
+
* se puede comprar, o una dependencia que no se puede satisfacer, salen
|
|
5873
|
+
* como `422` con el motivo en `message`.
|
|
5874
|
+
*
|
|
5875
|
+
* **Si el plan no lo incluye pero se vende** (`billing: addon`), instalarlo
|
|
5876
|
+
* es COMPRARLO: se cobra HOY el mes entero (una factura aparte al pagador)
|
|
5877
|
+
* y se suma a la suscripción de Stripe de la instancia para la
|
|
5878
|
+
* renovación, antes de activarlo; la fila queda marcada como añadido. Sin
|
|
5879
|
+
* plan de pago la respuesta es `402 subscription_required` con
|
|
5880
|
+
* `plan_url`; los demás cortes, con su código en `error`: `white_label`
|
|
5881
|
+
* (403), `not_the_payer` (403), `channel_seat` (422),
|
|
5882
|
+
* `stripe_price_missing` (503), `stripe_addon_failed` (502),
|
|
5883
|
+
* `addon_payment_failed` (402: la tarjeta no pasó; no se activa nada). Un
|
|
5884
|
+
* añadido que ya se está pagando no se cobra dos veces, y uno **pendiente
|
|
5885
|
+
* de baja** (`addon_ends_at`) se MANTIENE sin cobrar: vuelve a renovar
|
|
5886
|
+
* (`kept: true`, `charged: false`).
|
|
5887
|
+
*
|
|
5888
|
+
* Si el cobro entra pero el encendido revienta, la respuesta es `202` con
|
|
5889
|
+
* `status: pending` y `message`: el módulo se activa solo en unos minutos
|
|
5890
|
+
* (cola) y volver a pulsar no cobra otra vez. Otros cortes del cobro, con
|
|
5891
|
+
* su código: `addon_payment_requires_action` (402, el banco pide
|
|
5892
|
+
* confirmar y el panel aún no puede), `addon_payment_method_unsupported`
|
|
5893
|
+
* (402, sin tarjeta), `subscription_ending` (402, cancelada o en mora),
|
|
5894
|
+
* `addon_busy` (409), `addon_expired` (409).
|
|
5549
5895
|
*/
|
|
5550
5896
|
post: operations["tenantModules.install"];
|
|
5551
5897
|
delete?: never;
|
|
@@ -5564,12 +5910,28 @@ export interface paths {
|
|
|
5564
5910
|
get?: never;
|
|
5565
5911
|
put?: never;
|
|
5566
5912
|
/**
|
|
5567
|
-
* Desactiva un módulo de la instancia
|
|
5913
|
+
* Desactiva un módulo opcional de la instancia
|
|
5568
5914
|
* @description **Reservada al panel de Pimia.** Exige `admin:write`, que el Authorization Server emite SOLO al client de primera parte: un client de integrador no puede pedir ese scope —se le rechaza en el registro y no se le anuncia— y con cualquier otro token la llamada recibe `403`. Está en el contrato porque es el panel web de Pimia quien la consume, y sus tipos salen de aquí.
|
|
5569
5915
|
*
|
|
5570
|
-
* Un
|
|
5571
|
-
*
|
|
5572
|
-
*
|
|
5916
|
+
* Un básico, o un módulo del que dependa otro instalado, sale como `422`
|
|
5917
|
+
* con el motivo en `message`.
|
|
5918
|
+
*
|
|
5919
|
+
* **Si se estaba pagando como añadido** (fila `installed` con `meta.addon`
|
|
5920
|
+
* y una suscripción con partida), desactivarlo es **dejar de RENOVARLO**:
|
|
5921
|
+
* se resta de la partida de Stripe sin abono —el mes está pagado— y el
|
|
5922
|
+
* módulo SIGUE encendido hasta el fin del periodo (`addon_ends_at`); ahí
|
|
5923
|
+
* lo apaga `billing:apagar-anadidos-vencidos` (o la factura de
|
|
5924
|
+
* renovación). La respuesta lo dice: `status: installed`, `addon_released:
|
|
5925
|
+
* true`, `addon_ends_at`. Uno ya pendiente no cambia. Si Stripe no
|
|
5926
|
+
* contesta, el módulo sigue encendido y renovando: `502
|
|
5927
|
+
* stripe_addon_release_failed` o `stripe_period_unknown`.
|
|
5928
|
+
*
|
|
5929
|
+
* Un heredado (encendido sin marca) o un añadido sin partida se apaga en
|
|
5930
|
+
* el acto, como siempre: no hay nada pagado que respetar.
|
|
5931
|
+
*
|
|
5932
|
+
* **Un módulo activado por el integrador** (`meta.channel`, lo paga su
|
|
5933
|
+
* canal) no lo apaga el cliente: `403 channel_module`, con el nombre del
|
|
5934
|
+
* integrador en `message`.
|
|
5573
5935
|
*/
|
|
5574
5936
|
post: operations["tenantModules.disable"];
|
|
5575
5937
|
delete?: never;
|
|
@@ -11031,90 +11393,482 @@ export interface operations {
|
|
|
11031
11393
|
};
|
|
11032
11394
|
content: {
|
|
11033
11395
|
"application/json": {
|
|
11034
|
-
success: boolean;
|
|
11396
|
+
success: boolean;
|
|
11397
|
+
};
|
|
11398
|
+
};
|
|
11399
|
+
};
|
|
11400
|
+
404: components["responses"]["ModelNotFoundException"];
|
|
11401
|
+
};
|
|
11402
|
+
};
|
|
11403
|
+
"approvals.store": {
|
|
11404
|
+
parameters: {
|
|
11405
|
+
query?: never;
|
|
11406
|
+
header?: never;
|
|
11407
|
+
path?: never;
|
|
11408
|
+
cookie?: never;
|
|
11409
|
+
};
|
|
11410
|
+
requestBody: {
|
|
11411
|
+
content: {
|
|
11412
|
+
"application/json": components["schemas"]["StoreApprovalRequest"];
|
|
11413
|
+
};
|
|
11414
|
+
};
|
|
11415
|
+
responses: {
|
|
11416
|
+
201: {
|
|
11417
|
+
headers: {
|
|
11418
|
+
[name: string]: unknown;
|
|
11419
|
+
};
|
|
11420
|
+
content: {
|
|
11421
|
+
"application/json": {
|
|
11422
|
+
approval: {
|
|
11423
|
+
id: number;
|
|
11424
|
+
plane: string;
|
|
11425
|
+
title: string;
|
|
11426
|
+
task_type: string | null;
|
|
11427
|
+
context: unknown[] | null;
|
|
11428
|
+
/**
|
|
11429
|
+
* @description pending|in_progress|completed|failed — para el partner:
|
|
11430
|
+
* in_progress = pendiente de decisión; completed = aprobada;
|
|
11431
|
+
* failed = rechazada.
|
|
11432
|
+
*/
|
|
11433
|
+
status: string;
|
|
11434
|
+
proposal: unknown[] | null;
|
|
11435
|
+
/**
|
|
11436
|
+
* @description proposed|needs_changes|approved|rejected. `needs_changes` NO es
|
|
11437
|
+
* terminal: el owner pidió una revisión — en v1 el partner remite
|
|
11438
|
+
* una propuesta nueva (no hay PATCH) o espera la decisión.
|
|
11439
|
+
*/
|
|
11440
|
+
proposal_status: string | null;
|
|
11441
|
+
result: string | null;
|
|
11442
|
+
proposed_at: string;
|
|
11443
|
+
created_at: string;
|
|
11444
|
+
updated_at: string;
|
|
11445
|
+
};
|
|
11446
|
+
};
|
|
11447
|
+
};
|
|
11448
|
+
};
|
|
11449
|
+
403: {
|
|
11450
|
+
headers: {
|
|
11451
|
+
[name: string]: unknown;
|
|
11452
|
+
};
|
|
11453
|
+
content: {
|
|
11454
|
+
"application/json": {
|
|
11455
|
+
/** @constant */
|
|
11456
|
+
message: "Este endpoint exige un token OAuth de app de partner con el scope approvals:write.";
|
|
11457
|
+
};
|
|
11458
|
+
};
|
|
11459
|
+
};
|
|
11460
|
+
409: {
|
|
11461
|
+
headers: {
|
|
11462
|
+
[name: string]: unknown;
|
|
11463
|
+
};
|
|
11464
|
+
content: {
|
|
11465
|
+
"application/json": {
|
|
11466
|
+
/** @constant */
|
|
11467
|
+
message: "No hay un tenant en contexto para esta propuesta.";
|
|
11468
|
+
};
|
|
11469
|
+
};
|
|
11470
|
+
};
|
|
11471
|
+
422: components["responses"]["ValidationException"];
|
|
11472
|
+
};
|
|
11473
|
+
};
|
|
11474
|
+
"approvals.show": {
|
|
11475
|
+
parameters: {
|
|
11476
|
+
query?: never;
|
|
11477
|
+
header?: never;
|
|
11478
|
+
path: {
|
|
11479
|
+
id: number;
|
|
11480
|
+
};
|
|
11481
|
+
cookie?: never;
|
|
11482
|
+
};
|
|
11483
|
+
requestBody?: never;
|
|
11484
|
+
responses: {
|
|
11485
|
+
200: {
|
|
11486
|
+
headers: {
|
|
11487
|
+
[name: string]: unknown;
|
|
11488
|
+
};
|
|
11489
|
+
content: {
|
|
11490
|
+
"application/json": {
|
|
11491
|
+
approval: {
|
|
11492
|
+
id: number;
|
|
11493
|
+
plane: string;
|
|
11494
|
+
title: string;
|
|
11495
|
+
task_type: string | null;
|
|
11496
|
+
context: unknown[] | null;
|
|
11497
|
+
/**
|
|
11498
|
+
* @description pending|in_progress|completed|failed — para el partner:
|
|
11499
|
+
* in_progress = pendiente de decisión; completed = aprobada;
|
|
11500
|
+
* failed = rechazada.
|
|
11501
|
+
*/
|
|
11502
|
+
status: string;
|
|
11503
|
+
proposal: unknown[] | null;
|
|
11504
|
+
/**
|
|
11505
|
+
* @description proposed|needs_changes|approved|rejected. `needs_changes` NO es
|
|
11506
|
+
* terminal: el owner pidió una revisión — en v1 el partner remite
|
|
11507
|
+
* una propuesta nueva (no hay PATCH) o espera la decisión.
|
|
11508
|
+
*/
|
|
11509
|
+
proposal_status: string | null;
|
|
11510
|
+
result: string | null;
|
|
11511
|
+
proposed_at: string;
|
|
11512
|
+
created_at: string;
|
|
11513
|
+
updated_at: string;
|
|
11514
|
+
};
|
|
11515
|
+
};
|
|
11516
|
+
};
|
|
11517
|
+
};
|
|
11518
|
+
403: {
|
|
11519
|
+
headers: {
|
|
11520
|
+
[name: string]: unknown;
|
|
11521
|
+
};
|
|
11522
|
+
content: {
|
|
11523
|
+
"application/json": {
|
|
11524
|
+
/** @constant */
|
|
11525
|
+
message: "Este endpoint exige un token OAuth de app de partner con el scope approvals:write.";
|
|
11526
|
+
};
|
|
11527
|
+
};
|
|
11528
|
+
};
|
|
11529
|
+
409: {
|
|
11530
|
+
headers: {
|
|
11531
|
+
[name: string]: unknown;
|
|
11532
|
+
};
|
|
11533
|
+
content: {
|
|
11534
|
+
"application/json": {
|
|
11535
|
+
/** @constant */
|
|
11536
|
+
message: "No hay un tenant en contexto para esta propuesta.";
|
|
11537
|
+
};
|
|
11538
|
+
};
|
|
11539
|
+
};
|
|
11540
|
+
};
|
|
11541
|
+
};
|
|
11542
|
+
"apps.index": {
|
|
11543
|
+
parameters: {
|
|
11544
|
+
query?: never;
|
|
11545
|
+
header?: never;
|
|
11546
|
+
path?: never;
|
|
11547
|
+
cookie?: never;
|
|
11548
|
+
};
|
|
11549
|
+
requestBody?: never;
|
|
11550
|
+
responses: {
|
|
11551
|
+
200: {
|
|
11552
|
+
headers: {
|
|
11553
|
+
[name: string]: unknown;
|
|
11554
|
+
};
|
|
11555
|
+
content: {
|
|
11556
|
+
"application/json": {
|
|
11557
|
+
apps: {
|
|
11558
|
+
slug: string;
|
|
11559
|
+
name: string;
|
|
11560
|
+
description: string | null;
|
|
11561
|
+
publisher: string | null;
|
|
11562
|
+
kind: string;
|
|
11563
|
+
install: string[];
|
|
11564
|
+
scopes: string[];
|
|
11565
|
+
webhook_events: string[];
|
|
11566
|
+
config_url: string | null;
|
|
11567
|
+
price_cents: number | null;
|
|
11568
|
+
listed: boolean;
|
|
11569
|
+
status: string;
|
|
11570
|
+
installed: boolean;
|
|
11571
|
+
installed_at: string | null;
|
|
11572
|
+
disabled_at: string | null;
|
|
11573
|
+
installed_by: {
|
|
11574
|
+
id: number;
|
|
11575
|
+
name: string | null;
|
|
11576
|
+
} | null;
|
|
11577
|
+
authorization: {
|
|
11578
|
+
id: number;
|
|
11579
|
+
revoked: boolean;
|
|
11580
|
+
last_used_at: string | null;
|
|
11581
|
+
} | null;
|
|
11582
|
+
missing_required: string[];
|
|
11583
|
+
entry_credential: {
|
|
11584
|
+
set: boolean;
|
|
11585
|
+
last_four: string | null;
|
|
11586
|
+
created_at: string | null;
|
|
11587
|
+
last_used_at: string | null;
|
|
11588
|
+
};
|
|
11589
|
+
}[];
|
|
11590
|
+
installed_slugs: string[];
|
|
11591
|
+
};
|
|
11592
|
+
};
|
|
11593
|
+
};
|
|
11594
|
+
};
|
|
11595
|
+
};
|
|
11596
|
+
"apps.show": {
|
|
11597
|
+
parameters: {
|
|
11598
|
+
query?: never;
|
|
11599
|
+
header?: never;
|
|
11600
|
+
path: {
|
|
11601
|
+
slug: string;
|
|
11602
|
+
};
|
|
11603
|
+
cookie?: never;
|
|
11604
|
+
};
|
|
11605
|
+
requestBody?: never;
|
|
11606
|
+
responses: {
|
|
11607
|
+
200: {
|
|
11608
|
+
headers: {
|
|
11609
|
+
[name: string]: unknown;
|
|
11610
|
+
};
|
|
11611
|
+
content: {
|
|
11612
|
+
"application/json": {
|
|
11613
|
+
app: {
|
|
11614
|
+
slug: string;
|
|
11615
|
+
name: string;
|
|
11616
|
+
description: string | null;
|
|
11617
|
+
publisher: string | null;
|
|
11618
|
+
kind: string;
|
|
11619
|
+
install: string[];
|
|
11620
|
+
scopes: string[];
|
|
11621
|
+
webhook_events: string[];
|
|
11622
|
+
config_url: string | null;
|
|
11623
|
+
price_cents: number | null;
|
|
11624
|
+
listed: boolean;
|
|
11625
|
+
status: string;
|
|
11626
|
+
installed: boolean;
|
|
11627
|
+
installed_at: string | null;
|
|
11628
|
+
disabled_at: string | null;
|
|
11629
|
+
installed_by: {
|
|
11630
|
+
id: number;
|
|
11631
|
+
name: string | null;
|
|
11632
|
+
} | null;
|
|
11633
|
+
authorization: {
|
|
11634
|
+
id: number;
|
|
11635
|
+
revoked: boolean;
|
|
11636
|
+
last_used_at: string | null;
|
|
11637
|
+
} | null;
|
|
11638
|
+
missing_required: string[];
|
|
11639
|
+
entry_credential: {
|
|
11640
|
+
set: boolean;
|
|
11641
|
+
last_four: string | null;
|
|
11642
|
+
created_at: string | null;
|
|
11643
|
+
last_used_at: string | null;
|
|
11644
|
+
};
|
|
11645
|
+
config_schema: {
|
|
11646
|
+
[key: string]: {
|
|
11647
|
+
type: string;
|
|
11648
|
+
required: boolean;
|
|
11649
|
+
secret: boolean;
|
|
11650
|
+
};
|
|
11651
|
+
};
|
|
11652
|
+
config: {
|
|
11653
|
+
[key: string]: unknown;
|
|
11654
|
+
};
|
|
11655
|
+
};
|
|
11656
|
+
};
|
|
11657
|
+
};
|
|
11658
|
+
};
|
|
11659
|
+
};
|
|
11660
|
+
};
|
|
11661
|
+
"apps.install": {
|
|
11662
|
+
parameters: {
|
|
11663
|
+
query?: never;
|
|
11664
|
+
header?: never;
|
|
11665
|
+
path: {
|
|
11666
|
+
slug: string;
|
|
11667
|
+
};
|
|
11668
|
+
cookie?: never;
|
|
11669
|
+
};
|
|
11670
|
+
requestBody?: {
|
|
11671
|
+
content: {
|
|
11672
|
+
"application/json": {
|
|
11673
|
+
webhook_url?: string | null;
|
|
11674
|
+
};
|
|
11675
|
+
};
|
|
11676
|
+
};
|
|
11677
|
+
responses: {
|
|
11678
|
+
200: {
|
|
11679
|
+
headers: {
|
|
11680
|
+
[name: string]: unknown;
|
|
11681
|
+
};
|
|
11682
|
+
content: {
|
|
11683
|
+
"application/json": {
|
|
11684
|
+
app: {
|
|
11685
|
+
slug: string;
|
|
11686
|
+
name: string;
|
|
11687
|
+
description: string | null;
|
|
11688
|
+
publisher: string | null;
|
|
11689
|
+
kind: string;
|
|
11690
|
+
install: string[];
|
|
11691
|
+
scopes: string[];
|
|
11692
|
+
webhook_events: string[];
|
|
11693
|
+
config_url: string | null;
|
|
11694
|
+
price_cents: number | null;
|
|
11695
|
+
listed: boolean;
|
|
11696
|
+
status: string;
|
|
11697
|
+
installed: boolean;
|
|
11698
|
+
installed_at: string | null;
|
|
11699
|
+
disabled_at: string | null;
|
|
11700
|
+
installed_by: {
|
|
11701
|
+
id: number;
|
|
11702
|
+
name: string | null;
|
|
11703
|
+
} | null;
|
|
11704
|
+
authorization: {
|
|
11705
|
+
id: number;
|
|
11706
|
+
revoked: boolean;
|
|
11707
|
+
last_used_at: string | null;
|
|
11708
|
+
} | null;
|
|
11709
|
+
missing_required: string[];
|
|
11710
|
+
entry_credential: {
|
|
11711
|
+
set: boolean;
|
|
11712
|
+
last_four: string | null;
|
|
11713
|
+
created_at: string | null;
|
|
11714
|
+
last_used_at: string | null;
|
|
11715
|
+
};
|
|
11716
|
+
};
|
|
11717
|
+
webhook_secret?: string;
|
|
11718
|
+
entry_credential?: string;
|
|
11719
|
+
billing: {
|
|
11720
|
+
ok: boolean;
|
|
11721
|
+
charged?: boolean;
|
|
11722
|
+
already_paid?: boolean;
|
|
11723
|
+
free?: boolean;
|
|
11724
|
+
invoice?: string;
|
|
11725
|
+
};
|
|
11726
|
+
};
|
|
11727
|
+
};
|
|
11728
|
+
};
|
|
11729
|
+
422: components["responses"]["ValidationException"];
|
|
11730
|
+
};
|
|
11731
|
+
};
|
|
11732
|
+
"apps.uninstall": {
|
|
11733
|
+
parameters: {
|
|
11734
|
+
query?: never;
|
|
11735
|
+
header?: never;
|
|
11736
|
+
path: {
|
|
11737
|
+
slug: string;
|
|
11738
|
+
};
|
|
11739
|
+
cookie?: never;
|
|
11740
|
+
};
|
|
11741
|
+
requestBody?: never;
|
|
11742
|
+
responses: {
|
|
11743
|
+
200: {
|
|
11744
|
+
headers: {
|
|
11745
|
+
[name: string]: unknown;
|
|
11746
|
+
};
|
|
11747
|
+
content: {
|
|
11748
|
+
"application/json": {
|
|
11749
|
+
app: {
|
|
11750
|
+
slug: string;
|
|
11751
|
+
name: string;
|
|
11752
|
+
description: string | null;
|
|
11753
|
+
publisher: string | null;
|
|
11754
|
+
kind: string;
|
|
11755
|
+
install: string[];
|
|
11756
|
+
scopes: string[];
|
|
11757
|
+
webhook_events: string[];
|
|
11758
|
+
config_url: string | null;
|
|
11759
|
+
price_cents: number | null;
|
|
11760
|
+
listed: boolean;
|
|
11761
|
+
status: string;
|
|
11762
|
+
installed: boolean;
|
|
11763
|
+
installed_at: string | null;
|
|
11764
|
+
disabled_at: string | null;
|
|
11765
|
+
installed_by: {
|
|
11766
|
+
id: number;
|
|
11767
|
+
name: string | null;
|
|
11768
|
+
} | null;
|
|
11769
|
+
authorization: {
|
|
11770
|
+
id: number;
|
|
11771
|
+
revoked: boolean;
|
|
11772
|
+
last_used_at: string | null;
|
|
11773
|
+
} | null;
|
|
11774
|
+
missing_required: string[];
|
|
11775
|
+
entry_credential: {
|
|
11776
|
+
set: boolean;
|
|
11777
|
+
last_four: string | null;
|
|
11778
|
+
created_at: string | null;
|
|
11779
|
+
last_used_at: string | null;
|
|
11780
|
+
};
|
|
11781
|
+
};
|
|
11782
|
+
revoked_tokens: number;
|
|
11783
|
+
webhooks_removed: number;
|
|
11784
|
+
config_kept: boolean;
|
|
11785
|
+
billing: {
|
|
11786
|
+
ok: boolean;
|
|
11787
|
+
released?: boolean;
|
|
11788
|
+
kept_for_others?: boolean;
|
|
11789
|
+
free?: boolean;
|
|
11790
|
+
nothing_to_release?: boolean;
|
|
11791
|
+
release_failed?: boolean;
|
|
11792
|
+
paid_until?: string | null;
|
|
11793
|
+
};
|
|
11794
|
+
};
|
|
11795
|
+
};
|
|
11796
|
+
};
|
|
11797
|
+
};
|
|
11798
|
+
};
|
|
11799
|
+
"apps.config": {
|
|
11800
|
+
parameters: {
|
|
11801
|
+
query?: never;
|
|
11802
|
+
header?: never;
|
|
11803
|
+
path: {
|
|
11804
|
+
slug: string;
|
|
11805
|
+
};
|
|
11806
|
+
cookie?: never;
|
|
11807
|
+
};
|
|
11808
|
+
requestBody?: never;
|
|
11809
|
+
responses: {
|
|
11810
|
+
200: {
|
|
11811
|
+
headers: {
|
|
11812
|
+
[name: string]: unknown;
|
|
11813
|
+
};
|
|
11814
|
+
content: {
|
|
11815
|
+
"application/json": {
|
|
11816
|
+
config: {
|
|
11817
|
+
[key: string]: unknown;
|
|
11818
|
+
};
|
|
11819
|
+
config_schema: {
|
|
11820
|
+
[key: string]: {
|
|
11821
|
+
type: string;
|
|
11822
|
+
required: boolean;
|
|
11823
|
+
secret: boolean;
|
|
11824
|
+
};
|
|
11825
|
+
};
|
|
11826
|
+
missing_required: string[];
|
|
11035
11827
|
};
|
|
11036
11828
|
};
|
|
11037
11829
|
};
|
|
11038
|
-
404: components["responses"]["ModelNotFoundException"];
|
|
11039
11830
|
};
|
|
11040
11831
|
};
|
|
11041
|
-
"
|
|
11832
|
+
"apps.updateConfig": {
|
|
11042
11833
|
parameters: {
|
|
11043
11834
|
query?: never;
|
|
11044
11835
|
header?: never;
|
|
11045
|
-
path
|
|
11046
|
-
|
|
11047
|
-
};
|
|
11048
|
-
requestBody: {
|
|
11049
|
-
content: {
|
|
11050
|
-
"application/json": components["schemas"]["StoreApprovalRequest"];
|
|
11836
|
+
path: {
|
|
11837
|
+
slug: string;
|
|
11051
11838
|
};
|
|
11839
|
+
cookie?: never;
|
|
11052
11840
|
};
|
|
11841
|
+
requestBody?: never;
|
|
11053
11842
|
responses: {
|
|
11054
|
-
|
|
11843
|
+
200: {
|
|
11055
11844
|
headers: {
|
|
11056
11845
|
[name: string]: unknown;
|
|
11057
11846
|
};
|
|
11058
11847
|
content: {
|
|
11059
11848
|
"application/json": {
|
|
11060
|
-
|
|
11061
|
-
|
|
11062
|
-
plane: string;
|
|
11063
|
-
title: string;
|
|
11064
|
-
task_type: string | null;
|
|
11065
|
-
context: unknown[] | null;
|
|
11066
|
-
/**
|
|
11067
|
-
* @description pending|in_progress|completed|failed — para el partner:
|
|
11068
|
-
* in_progress = pendiente de decisión; completed = aprobada;
|
|
11069
|
-
* failed = rechazada.
|
|
11070
|
-
*/
|
|
11071
|
-
status: string;
|
|
11072
|
-
proposal: unknown[] | null;
|
|
11073
|
-
/**
|
|
11074
|
-
* @description proposed|needs_changes|approved|rejected. `needs_changes` NO es
|
|
11075
|
-
* terminal: el owner pidió una revisión — en v1 el partner remite
|
|
11076
|
-
* una propuesta nueva (no hay PATCH) o espera la decisión.
|
|
11077
|
-
*/
|
|
11078
|
-
proposal_status: string | null;
|
|
11079
|
-
result: string | null;
|
|
11080
|
-
proposed_at: string;
|
|
11081
|
-
created_at: string;
|
|
11082
|
-
updated_at: string;
|
|
11849
|
+
config: {
|
|
11850
|
+
[key: string]: unknown;
|
|
11083
11851
|
};
|
|
11084
|
-
|
|
11085
|
-
|
|
11086
|
-
|
|
11087
|
-
|
|
11088
|
-
|
|
11089
|
-
|
|
11090
|
-
|
|
11091
|
-
|
|
11092
|
-
"application/json": {
|
|
11093
|
-
/** @constant */
|
|
11094
|
-
message: "Este endpoint exige un token OAuth de app de partner con el scope approvals:write.";
|
|
11095
|
-
};
|
|
11096
|
-
};
|
|
11097
|
-
};
|
|
11098
|
-
409: {
|
|
11099
|
-
headers: {
|
|
11100
|
-
[name: string]: unknown;
|
|
11101
|
-
};
|
|
11102
|
-
content: {
|
|
11103
|
-
"application/json": {
|
|
11104
|
-
/** @constant */
|
|
11105
|
-
message: "No hay un tenant en contexto para esta propuesta.";
|
|
11852
|
+
config_schema: {
|
|
11853
|
+
[key: string]: {
|
|
11854
|
+
type: string;
|
|
11855
|
+
required: boolean;
|
|
11856
|
+
secret: boolean;
|
|
11857
|
+
};
|
|
11858
|
+
};
|
|
11859
|
+
missing_required: string[];
|
|
11106
11860
|
};
|
|
11107
11861
|
};
|
|
11108
11862
|
};
|
|
11109
11863
|
422: components["responses"]["ValidationException"];
|
|
11110
11864
|
};
|
|
11111
11865
|
};
|
|
11112
|
-
"
|
|
11866
|
+
"apps.rotateCredential": {
|
|
11113
11867
|
parameters: {
|
|
11114
11868
|
query?: never;
|
|
11115
11869
|
header?: never;
|
|
11116
11870
|
path: {
|
|
11117
|
-
|
|
11871
|
+
slug: string;
|
|
11118
11872
|
};
|
|
11119
11873
|
cookie?: never;
|
|
11120
11874
|
};
|
|
@@ -11126,52 +11880,8 @@ export interface operations {
|
|
|
11126
11880
|
};
|
|
11127
11881
|
content: {
|
|
11128
11882
|
"application/json": {
|
|
11129
|
-
|
|
11130
|
-
|
|
11131
|
-
plane: string;
|
|
11132
|
-
title: string;
|
|
11133
|
-
task_type: string | null;
|
|
11134
|
-
context: unknown[] | null;
|
|
11135
|
-
/**
|
|
11136
|
-
* @description pending|in_progress|completed|failed — para el partner:
|
|
11137
|
-
* in_progress = pendiente de decisión; completed = aprobada;
|
|
11138
|
-
* failed = rechazada.
|
|
11139
|
-
*/
|
|
11140
|
-
status: string;
|
|
11141
|
-
proposal: unknown[] | null;
|
|
11142
|
-
/**
|
|
11143
|
-
* @description proposed|needs_changes|approved|rejected. `needs_changes` NO es
|
|
11144
|
-
* terminal: el owner pidió una revisión — en v1 el partner remite
|
|
11145
|
-
* una propuesta nueva (no hay PATCH) o espera la decisión.
|
|
11146
|
-
*/
|
|
11147
|
-
proposal_status: string | null;
|
|
11148
|
-
result: string | null;
|
|
11149
|
-
proposed_at: string;
|
|
11150
|
-
created_at: string;
|
|
11151
|
-
updated_at: string;
|
|
11152
|
-
};
|
|
11153
|
-
};
|
|
11154
|
-
};
|
|
11155
|
-
};
|
|
11156
|
-
403: {
|
|
11157
|
-
headers: {
|
|
11158
|
-
[name: string]: unknown;
|
|
11159
|
-
};
|
|
11160
|
-
content: {
|
|
11161
|
-
"application/json": {
|
|
11162
|
-
/** @constant */
|
|
11163
|
-
message: "Este endpoint exige un token OAuth de app de partner con el scope approvals:write.";
|
|
11164
|
-
};
|
|
11165
|
-
};
|
|
11166
|
-
};
|
|
11167
|
-
409: {
|
|
11168
|
-
headers: {
|
|
11169
|
-
[name: string]: unknown;
|
|
11170
|
-
};
|
|
11171
|
-
content: {
|
|
11172
|
-
"application/json": {
|
|
11173
|
-
/** @constant */
|
|
11174
|
-
message: "No hay un tenant en contexto para esta propuesta.";
|
|
11883
|
+
entry_credential: string;
|
|
11884
|
+
app: string;
|
|
11175
11885
|
};
|
|
11176
11886
|
};
|
|
11177
11887
|
};
|
|
@@ -13772,6 +14482,121 @@ export interface operations {
|
|
|
13772
14482
|
};
|
|
13773
14483
|
};
|
|
13774
14484
|
};
|
|
14485
|
+
"desarrolladorLink.status": {
|
|
14486
|
+
parameters: {
|
|
14487
|
+
query?: never;
|
|
14488
|
+
header?: never;
|
|
14489
|
+
path?: never;
|
|
14490
|
+
cookie?: never;
|
|
14491
|
+
};
|
|
14492
|
+
requestBody?: never;
|
|
14493
|
+
responses: {
|
|
14494
|
+
200: {
|
|
14495
|
+
headers: {
|
|
14496
|
+
[name: string]: unknown;
|
|
14497
|
+
};
|
|
14498
|
+
content: {
|
|
14499
|
+
"application/json": {
|
|
14500
|
+
data: {
|
|
14501
|
+
id: number;
|
|
14502
|
+
status: string;
|
|
14503
|
+
link_code: string;
|
|
14504
|
+
/** Format: date-time */
|
|
14505
|
+
requested_at: string | null;
|
|
14506
|
+
/** Format: date-time */
|
|
14507
|
+
accepted_at: string | null;
|
|
14508
|
+
desarrollador: {
|
|
14509
|
+
id: string | null;
|
|
14510
|
+
name: string | null;
|
|
14511
|
+
email: string | null;
|
|
14512
|
+
};
|
|
14513
|
+
/**
|
|
14514
|
+
* @description Lo que el dueño de la instancia debe tener claro al vincular.
|
|
14515
|
+
* @constant
|
|
14516
|
+
*/
|
|
14517
|
+
alcance: "Este vínculo es administrativo y de facturación. No da acceso a tus datos: eso lo autorizas tú desde «Apps conectadas», permiso a permiso.";
|
|
14518
|
+
} | {
|
|
14519
|
+
/** @constant */
|
|
14520
|
+
status: "none";
|
|
14521
|
+
};
|
|
14522
|
+
};
|
|
14523
|
+
};
|
|
14524
|
+
};
|
|
14525
|
+
404: components["responses"]["ModelNotFoundException"];
|
|
14526
|
+
};
|
|
14527
|
+
};
|
|
14528
|
+
"desarrolladorLink.request": {
|
|
14529
|
+
parameters: {
|
|
14530
|
+
query?: never;
|
|
14531
|
+
header?: never;
|
|
14532
|
+
path?: never;
|
|
14533
|
+
cookie?: never;
|
|
14534
|
+
};
|
|
14535
|
+
requestBody: {
|
|
14536
|
+
content: {
|
|
14537
|
+
"application/json": {
|
|
14538
|
+
link_code: string;
|
|
14539
|
+
};
|
|
14540
|
+
};
|
|
14541
|
+
};
|
|
14542
|
+
responses: {
|
|
14543
|
+
201: {
|
|
14544
|
+
headers: {
|
|
14545
|
+
[name: string]: unknown;
|
|
14546
|
+
};
|
|
14547
|
+
content: {
|
|
14548
|
+
"application/json": {
|
|
14549
|
+
/** @constant */
|
|
14550
|
+
message: "Solicitud enviada al desarrollador.";
|
|
14551
|
+
data: {
|
|
14552
|
+
id: number;
|
|
14553
|
+
status: string;
|
|
14554
|
+
link_code: string;
|
|
14555
|
+
/** Format: date-time */
|
|
14556
|
+
requested_at: string | null;
|
|
14557
|
+
/** Format: date-time */
|
|
14558
|
+
accepted_at: string | null;
|
|
14559
|
+
desarrollador: {
|
|
14560
|
+
id: string | null;
|
|
14561
|
+
name: string | null;
|
|
14562
|
+
email: string | null;
|
|
14563
|
+
};
|
|
14564
|
+
/**
|
|
14565
|
+
* @description Lo que el dueño de la instancia debe tener claro al vincular.
|
|
14566
|
+
* @constant
|
|
14567
|
+
*/
|
|
14568
|
+
alcance: "Este vínculo es administrativo y de facturación. No da acceso a tus datos: eso lo autorizas tú desde «Apps conectadas», permiso a permiso.";
|
|
14569
|
+
};
|
|
14570
|
+
};
|
|
14571
|
+
};
|
|
14572
|
+
};
|
|
14573
|
+
404: components["responses"]["ModelNotFoundException"];
|
|
14574
|
+
422: components["responses"]["ValidationException"];
|
|
14575
|
+
};
|
|
14576
|
+
};
|
|
14577
|
+
"desarrolladorLink.revoke": {
|
|
14578
|
+
parameters: {
|
|
14579
|
+
query?: never;
|
|
14580
|
+
header?: never;
|
|
14581
|
+
path?: never;
|
|
14582
|
+
cookie?: never;
|
|
14583
|
+
};
|
|
14584
|
+
requestBody?: never;
|
|
14585
|
+
responses: {
|
|
14586
|
+
200: {
|
|
14587
|
+
headers: {
|
|
14588
|
+
[name: string]: unknown;
|
|
14589
|
+
};
|
|
14590
|
+
content: {
|
|
14591
|
+
"application/json": {
|
|
14592
|
+
/** @constant */
|
|
14593
|
+
message: "Vinculación revocada.";
|
|
14594
|
+
};
|
|
14595
|
+
};
|
|
14596
|
+
};
|
|
14597
|
+
404: components["responses"]["ModelNotFoundException"];
|
|
14598
|
+
};
|
|
14599
|
+
};
|
|
13775
14600
|
"eInvoice.download": {
|
|
13776
14601
|
parameters: {
|
|
13777
14602
|
query?: {
|
|
@@ -21920,9 +22745,36 @@ export interface operations {
|
|
|
21920
22745
|
max_storage_mb: number;
|
|
21921
22746
|
features: string[];
|
|
21922
22747
|
is_free: boolean;
|
|
22748
|
+
optional_modules: {
|
|
22749
|
+
slug: string;
|
|
22750
|
+
name: string;
|
|
22751
|
+
description: string | null;
|
|
22752
|
+
included: boolean;
|
|
22753
|
+
addon: boolean;
|
|
22754
|
+
price_cents: number | null;
|
|
22755
|
+
price: string | null;
|
|
22756
|
+
}[];
|
|
21923
22757
|
}[];
|
|
21924
22758
|
white_label: boolean;
|
|
21925
22759
|
message: string | null;
|
|
22760
|
+
catalogo: {
|
|
22761
|
+
integrador: {
|
|
22762
|
+
nombre: string;
|
|
22763
|
+
soporte_url: string | null;
|
|
22764
|
+
soporte_email: string | null;
|
|
22765
|
+
};
|
|
22766
|
+
currency: string;
|
|
22767
|
+
items: {
|
|
22768
|
+
kind: string;
|
|
22769
|
+
slug: string;
|
|
22770
|
+
name: string;
|
|
22771
|
+
description: string | null;
|
|
22772
|
+
price_cents: number;
|
|
22773
|
+
price: string;
|
|
22774
|
+
contract_url: string | null;
|
|
22775
|
+
active: boolean | null;
|
|
22776
|
+
}[];
|
|
22777
|
+
} | null;
|
|
21926
22778
|
};
|
|
21927
22779
|
};
|
|
21928
22780
|
};
|
|
@@ -21980,6 +22832,11 @@ export interface operations {
|
|
|
21980
22832
|
mode: string;
|
|
21981
22833
|
white_label: boolean;
|
|
21982
22834
|
can_manage: boolean;
|
|
22835
|
+
integrador: {
|
|
22836
|
+
nombre: string;
|
|
22837
|
+
soporte_url: string | null;
|
|
22838
|
+
soporte_email: string | null;
|
|
22839
|
+
} | null;
|
|
21983
22840
|
seat: {
|
|
21984
22841
|
role: string;
|
|
21985
22842
|
grace_until: string | null;
|
|
@@ -21992,6 +22849,24 @@ export interface operations {
|
|
|
21992
22849
|
cancel_at_period_end: boolean;
|
|
21993
22850
|
ends_at: string | null;
|
|
21994
22851
|
} | null;
|
|
22852
|
+
apps: {
|
|
22853
|
+
items: {
|
|
22854
|
+
slug: string;
|
|
22855
|
+
name: string;
|
|
22856
|
+
price_cents: number;
|
|
22857
|
+
price: string;
|
|
22858
|
+
quantity: number;
|
|
22859
|
+
}[];
|
|
22860
|
+
total_cents: number;
|
|
22861
|
+
total: string;
|
|
22862
|
+
} | null;
|
|
22863
|
+
addons: {
|
|
22864
|
+
quantity: number;
|
|
22865
|
+
price_cents: number;
|
|
22866
|
+
price: string;
|
|
22867
|
+
total_cents: number;
|
|
22868
|
+
total: string;
|
|
22869
|
+
} | null;
|
|
21995
22870
|
status: string;
|
|
21996
22871
|
};
|
|
21997
22872
|
};
|
|
@@ -22007,7 +22882,14 @@ export interface operations {
|
|
|
22007
22882
|
path?: never;
|
|
22008
22883
|
cookie?: never;
|
|
22009
22884
|
};
|
|
22010
|
-
requestBody
|
|
22885
|
+
requestBody: {
|
|
22886
|
+
content: {
|
|
22887
|
+
"application/json": {
|
|
22888
|
+
plan_id: number;
|
|
22889
|
+
modules?: string[];
|
|
22890
|
+
};
|
|
22891
|
+
};
|
|
22892
|
+
};
|
|
22011
22893
|
responses: {
|
|
22012
22894
|
200: {
|
|
22013
22895
|
headers: {
|
|
@@ -22019,10 +22901,14 @@ export interface operations {
|
|
|
22019
22901
|
checkout_url: string | null;
|
|
22020
22902
|
resumed: boolean;
|
|
22021
22903
|
plan: string | null;
|
|
22904
|
+
addons: string[];
|
|
22905
|
+
addons_failed: boolean;
|
|
22906
|
+
addons_message: string | null;
|
|
22022
22907
|
};
|
|
22023
22908
|
};
|
|
22024
22909
|
};
|
|
22025
22910
|
};
|
|
22911
|
+
422: components["responses"]["ValidationException"];
|
|
22026
22912
|
};
|
|
22027
22913
|
};
|
|
22028
22914
|
"tenantBilling.portal": {
|
|
@@ -22422,6 +23308,13 @@ export interface operations {
|
|
|
22422
23308
|
abilities_namespace: string | null;
|
|
22423
23309
|
status: string;
|
|
22424
23310
|
available_in_plan: boolean;
|
|
23311
|
+
billing: string;
|
|
23312
|
+
price_cents: number | null;
|
|
23313
|
+
price: string | null;
|
|
23314
|
+
purchasable: boolean;
|
|
23315
|
+
contract_url: string | null;
|
|
23316
|
+
addon_active: boolean;
|
|
23317
|
+
addon_ends_at: string | null;
|
|
22425
23318
|
installed_at: string | null;
|
|
22426
23319
|
disabled_at: string | null;
|
|
22427
23320
|
version: string | null;
|
|
@@ -22431,6 +23324,12 @@ export interface operations {
|
|
|
22431
23324
|
dependents: string[];
|
|
22432
23325
|
}[];
|
|
22433
23326
|
installed_slugs: string[];
|
|
23327
|
+
addons: {
|
|
23328
|
+
price_cents: number;
|
|
23329
|
+
price: string;
|
|
23330
|
+
quantity: number;
|
|
23331
|
+
purchasable: boolean;
|
|
23332
|
+
};
|
|
22434
23333
|
};
|
|
22435
23334
|
};
|
|
22436
23335
|
};
|
|
@@ -22461,6 +23360,9 @@ export interface operations {
|
|
|
22461
23360
|
status: string;
|
|
22462
23361
|
installed_at: string | null;
|
|
22463
23362
|
installed_slugs: string[];
|
|
23363
|
+
addon: boolean;
|
|
23364
|
+
charged: boolean;
|
|
23365
|
+
kept: boolean;
|
|
22464
23366
|
};
|
|
22465
23367
|
};
|
|
22466
23368
|
};
|
|
@@ -22489,6 +23391,8 @@ export interface operations {
|
|
|
22489
23391
|
status: string;
|
|
22490
23392
|
disabled_at: string | null;
|
|
22491
23393
|
installed_slugs: string[];
|
|
23394
|
+
addon_released: boolean;
|
|
23395
|
+
addon_ends_at: string | null;
|
|
22492
23396
|
};
|
|
22493
23397
|
};
|
|
22494
23398
|
};
|