@pimia/sdk 0.21.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 CHANGED
@@ -63,6 +63,53 @@ cliente exige un `TokenStore` en lugar de un string: persiste el conjunto de
63
63
  tokens tras cada refresco y no refresques dos veces en paralelo con el mismo
64
64
  token. Las dos cosas las cubre el SDK si lo usas como está pensado.
65
65
 
66
+ ## Un servicio que reenvía el token de su usuario
67
+
68
+ Todo lo de arriba supone que **tu app posee un grant**. Hay integraciones que no
69
+ y que no deben: un servicio al que el front le manda, en cada petición, el
70
+ `Authorization` del usuario que ya entró en Pimia. Para ésas está el modo de
71
+ token prestado — sin `clientId`, sin `TokenStore` y sin ceremonia OAuth:
72
+
73
+ ```ts
74
+ const pimia = PimiaClient.withBorrowedToken({
75
+ baseUrl: `https://${tenant}.pimia.es`,
76
+ accessToken: bearerDeQuienLlama,
77
+ // La empresa activa viaja en cabecera, como en todo el API. OMÍTELA cuando no
78
+ // la sepas: `company:` vacía es una cabecera presente que no casa con ninguna
79
+ // empresa.
80
+ headers: empresa === null ? {} : { company: String(empresa) },
81
+ // Atiendes una petición web: los reintentos del SDK ESPERAN, y esperar dentro
82
+ // de la petición de un usuario es una petición colgada.
83
+ maxRateLimitRetries: 0,
84
+ })
85
+
86
+ const empresaActiva = await pimia.bootstrap.currentCompanyId()
87
+ const censo = await pimia.crm.assignableUsers()
88
+ ```
89
+
90
+ Lo que ganas con esto es que **Pimia sigue decidiendo los permisos**: tu servicio
91
+ no puede darle a nadie más de lo que su token ya le daba, y no hay una
92
+ credencial de servicio que auditar aparte.
93
+
94
+ Tres cosas que conviene tener claras:
95
+
96
+ - **Un cliente por petición.** El token vive lo que viva la petición que lo
97
+ trajo; una instancia compartida es una credencial compartida.
98
+ - **No se refresca.** El refresh es del dueño del grant. Cuando el token caduca,
99
+ el 401 sube como `UnauthorizedError` y quien tiene que conseguir otro es quien
100
+ te lo prestó. El cliente no lo intenta —y eso es deliberado: con la rotación
101
+ de Pimia, tocar el refresh de otro revoca su grant entero.
102
+ - **`pimia.oauth` es `null`** en este modo. No hay ceremonia que hacer, y un
103
+ `OAuth` sin `clientId` compondría una URL de autorización rota que sólo
104
+ fallaría en el navegador del usuario.
105
+
106
+ `GET /bootstrap` merece un aviso propio: **es la única respuesta del API que no
107
+ viene envuelta en `data`**. Sus claves cuelgan de la raíz, así que un
108
+ desenvolvedor de `data` escrito «para todas las llamadas» devuelve vacío sin
109
+ error — y el fallo se ve como una empresa sin resolver o como una moneda que cae
110
+ al respaldo, nunca como un fallo. `pimia.bootstrap.currentCompanyId()` y
111
+ `.currency()` lo leen bien; `.get()` te da el cuerpo tal cual.
112
+
66
113
  ## Reintentar un `POST` sin duplicar
67
114
 
68
115
  Manda una `Idempotency-Key` única por operación y Pimia ejecuta la escritura
@@ -199,6 +246,39 @@ Detalles que ahorran un rato:
199
246
  - `signWebhook()` firma un cuerpo como lo haría Pimia: úsalo en **tus tests**,
200
247
  no en producción.
201
248
 
249
+ ## El plano central: la cartera del integrador
250
+
251
+ Si eres integrador (una cuenta de **desarrollador** en Pimia), tu cartera, tus
252
+ clients OAuth, las invitaciones, el patrocinio y el traspaso viven en el
253
+ **plano central** (`https://pimia.es/api`), no en la API de un tenant. Es otro
254
+ cliente y otra credencial: el **token personal** de tu cuenta, no un token
255
+ OAuth de instancia.
256
+
257
+ ```ts
258
+ import { PimiaCentralClient, MissingAbilityError } from '@pimia/sdk'
259
+
260
+ const central = new PimiaCentralClient({
261
+ baseUrl: 'https://pimia.es',
262
+ token: () => process.env.PIMIA_CENTRAL_TOKEN!,
263
+ })
264
+
265
+ const { data } = await central.overview() // tu cartera, con la atribución
266
+ await central.invitations.create({ // el cliente nace dueño; pagas tú
267
+ email: 'ana@talleres-ana.es',
268
+ company_name: 'Talleres Ana',
269
+ billing: 'sponsor',
270
+ })
271
+ await central.sponsorship.sponsor({ tenant_slug: 'talleres-ana', plan_id: 6 })
272
+ ```
273
+
274
+ El token está acotado por plano: `desarrollador` abre `/desarrollador/*` y
275
+ `central` abre invitaciones, patrocinio y traspaso. Si al tuyo le falta una,
276
+ la llamada lanza `MissingAbilityError` con `ability` diciendo cuál. Lo que el
277
+ plano central NO da es contenido fiscal de ningún cliente: a los datos de una
278
+ instancia se llega por OAuth consentido, con `PimiaClient`.
279
+
280
+ Los tipos salen de `spec/pimia-central-v1.json` (`@pimia/sdk/central-api`).
281
+
202
282
  ## Más
203
283
 
204
284
  Documentación completa, modelo mental (un tenant = una base URL = un token),