@hablala/api-contract 0.10.0 → 0.11.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/dist/index.d.ts CHANGED
@@ -264,6 +264,26 @@ interface paths {
264
264
  patch?: never;
265
265
  trace?: never;
266
266
  };
267
+ "/v1/invitations": {
268
+ parameters: {
269
+ query?: never;
270
+ header?: never;
271
+ path?: never;
272
+ cookie?: never;
273
+ };
274
+ get?: never;
275
+ put?: never;
276
+ /**
277
+ * Invitar a un operador por email (bootstrap del equipo, credencial de máquina)
278
+ * @description Crea una invitación por **email** con un rol opcional (`{"invitation": {"email": "…", "role_id": "role_…"}}`). Al aceptarla, la persona queda como miembro de la organización y podrá iniciar sesión como operador (member session `mem_…`). La org sale del token (org-less), como el resto de la superficie de máquina. Requiere el permiso `invitations:create` (preset `team_admin`).
279
+ */
280
+ post: operations["post /v1/invitations"];
281
+ delete?: never;
282
+ options?: never;
283
+ head?: never;
284
+ patch?: never;
285
+ trace?: never;
286
+ };
267
287
  "/v1/invitations/accept": {
268
288
  parameters: {
269
289
  query?: never;
@@ -1107,6 +1127,26 @@ interface paths {
1107
1127
  patch?: never;
1108
1128
  trace?: never;
1109
1129
  };
1130
+ "/v1/members": {
1131
+ parameters: {
1132
+ query?: never;
1133
+ header?: never;
1134
+ path?: never;
1135
+ cookie?: never;
1136
+ };
1137
+ get?: never;
1138
+ put?: never;
1139
+ /**
1140
+ * Dar de alta un operador directo (sin invitación)
1141
+ * @description Crea al operador y su membresía ACTIVA al instante. Devuelve un `passwordSetupToken` para que la persona fije su contraseña (no se comparte ninguna contraseña generada). Requiere `organization_memberships:create` (preset `team_admin`).
1142
+ */
1143
+ post: operations["post /v1/members"];
1144
+ delete?: never;
1145
+ options?: never;
1146
+ head?: never;
1147
+ patch?: never;
1148
+ trace?: never;
1149
+ };
1110
1150
  "/v1/members/me": {
1111
1151
  parameters: {
1112
1152
  query?: never;
@@ -4285,6 +4325,23 @@ interface paths {
4285
4325
  patch?: never;
4286
4326
  trace?: never;
4287
4327
  };
4328
+ "/v1/roles": {
4329
+ parameters: {
4330
+ query?: never;
4331
+ header?: never;
4332
+ path?: never;
4333
+ cookie?: never;
4334
+ };
4335
+ /** Listar los roles de la organización (para asignar al invitar) */
4336
+ get: operations["get /v1/roles"];
4337
+ put?: never;
4338
+ post?: never;
4339
+ delete?: never;
4340
+ options?: never;
4341
+ head?: never;
4342
+ patch?: never;
4343
+ trace?: never;
4344
+ };
4288
4345
  "/v1/sso/callback": {
4289
4346
  parameters: {
4290
4347
  query?: never;
@@ -8095,6 +8152,40 @@ interface components {
8095
8152
  /** @description Destino de la subida. */
8096
8153
  url: string;
8097
8154
  };
8155
+ /**
8156
+ * ProvisionMemberInput
8157
+ * @description Datos para dar de alta un operador DIRECTO (sin invitación por email): queda miembro activo al instante y establece su contraseña por el link de set-password de la respuesta.
8158
+ */
8159
+ ProvisionMemberInput: {
8160
+ /**
8161
+ * Format: email
8162
+ * @description Email del operador. Si ya existe un usuario con ese email, se reutiliza.
8163
+ */
8164
+ email: string;
8165
+ /** @description Nombre del rol a asignar (p. ej. `operator`). Opcional. */
8166
+ role?: string | null;
8167
+ };
8168
+ /** ProvisionMemberRequest */
8169
+ ProvisionMemberRequest: {
8170
+ member: components["schemas"]["ProvisionMemberInput"];
8171
+ };
8172
+ /**
8173
+ * ProvisionMemberResponse
8174
+ * @description El operador dado de alta. `passwordSetupToken` es el token de un solo uso con el que la persona establece SU contraseña (nunca se le comparte una contraseña generada). `userCreated` indica si el usuario nació con esta alta o ya existía (en cuyo caso su contraseña no se toca).
8175
+ */
8176
+ ProvisionMemberResponse: {
8177
+ data: {
8178
+ displayName?: string | null;
8179
+ email?: string | null;
8180
+ /** @description Id de la membresía (`mbr_…`). */
8181
+ id: string;
8182
+ /** @description Token de set-password (un solo uso). Entrégaselo a la persona para que fije su contraseña vía el flujo de reset. NO es una contraseña. */
8183
+ passwordSetupToken: string;
8184
+ roles: string[];
8185
+ /** @description `true` si el usuario nació con esta alta; `false` si ya existía. */
8186
+ userCreated: boolean;
8187
+ };
8188
+ };
8098
8189
  /**
8099
8190
  * PublicOrganization
8100
8191
  * @description Identidad PÚBLICA del tenant (la org del token) — el paralelo horizontal del `shop`/`brand` de Shopify. Deja al cliente pintar su chrome (nombre, logo) y conocer su `endUserObjectSlug` sin hardcodear la marca. NUNCA incluye la PII legal del negocio.
@@ -9616,6 +9707,49 @@ interface operations {
9616
9707
  };
9617
9708
  };
9618
9709
  };
9710
+ "post /v1/invitations": {
9711
+ parameters: {
9712
+ query?: never;
9713
+ header?: never;
9714
+ path?: never;
9715
+ cookie?: never;
9716
+ };
9717
+ /** @description Datos de la invitación */
9718
+ requestBody?: {
9719
+ content: {
9720
+ "application/json": components["schemas"]["InvitationRequest"];
9721
+ };
9722
+ };
9723
+ responses: {
9724
+ /** @description Invitación creada */
9725
+ 201: {
9726
+ headers: {
9727
+ [name: string]: unknown;
9728
+ };
9729
+ content: {
9730
+ "application/json": components["schemas"]["InvitationResponse"];
9731
+ };
9732
+ };
9733
+ /** @description Sin permiso */
9734
+ 403: {
9735
+ headers: {
9736
+ [name: string]: unknown;
9737
+ };
9738
+ content: {
9739
+ "application/json": components["schemas"]["Error"];
9740
+ };
9741
+ };
9742
+ /** @description Error de validación */
9743
+ 422: {
9744
+ headers: {
9745
+ [name: string]: unknown;
9746
+ };
9747
+ content: {
9748
+ "application/json": components["schemas"]["Error"];
9749
+ };
9750
+ };
9751
+ };
9752
+ };
9619
9753
  "post /v1/invitations/accept": {
9620
9754
  parameters: {
9621
9755
  query?: never;
@@ -11236,6 +11370,49 @@ interface operations {
11236
11370
  };
11237
11371
  };
11238
11372
  };
11373
+ "post /v1/members": {
11374
+ parameters: {
11375
+ query?: never;
11376
+ header?: never;
11377
+ path?: never;
11378
+ cookie?: never;
11379
+ };
11380
+ /** @description Datos del operador */
11381
+ requestBody?: {
11382
+ content: {
11383
+ "application/json": components["schemas"]["ProvisionMemberRequest"];
11384
+ };
11385
+ };
11386
+ responses: {
11387
+ /** @description Operador dado de alta */
11388
+ 201: {
11389
+ headers: {
11390
+ [name: string]: unknown;
11391
+ };
11392
+ content: {
11393
+ "application/json": components["schemas"]["ProvisionMemberResponse"];
11394
+ };
11395
+ };
11396
+ /** @description Sin permiso */
11397
+ 403: {
11398
+ headers: {
11399
+ [name: string]: unknown;
11400
+ };
11401
+ content: {
11402
+ "application/json": components["schemas"]["Error"];
11403
+ };
11404
+ };
11405
+ /** @description Error de validación */
11406
+ 422: {
11407
+ headers: {
11408
+ [name: string]: unknown;
11409
+ };
11410
+ content: {
11411
+ "application/json": components["schemas"]["Error"];
11412
+ };
11413
+ };
11414
+ };
11415
+ };
11239
11416
  "get /v1/members/me": {
11240
11417
  parameters: {
11241
11418
  query?: never;
@@ -20353,6 +20530,35 @@ interface operations {
20353
20530
  };
20354
20531
  };
20355
20532
  };
20533
+ "get /v1/roles": {
20534
+ parameters: {
20535
+ query?: never;
20536
+ header?: never;
20537
+ path?: never;
20538
+ cookie?: never;
20539
+ };
20540
+ requestBody?: never;
20541
+ responses: {
20542
+ /** @description Roles */
20543
+ 200: {
20544
+ headers: {
20545
+ [name: string]: unknown;
20546
+ };
20547
+ content: {
20548
+ "application/json": components["schemas"]["RolesResponse"];
20549
+ };
20550
+ };
20551
+ /** @description Sin permiso */
20552
+ 403: {
20553
+ headers: {
20554
+ [name: string]: unknown;
20555
+ };
20556
+ content: {
20557
+ "application/json": components["schemas"]["Error"];
20558
+ };
20559
+ };
20560
+ };
20561
+ };
20356
20562
  "post /v1/sso/callback": {
20357
20563
  parameters: {
20358
20564
  query?: never;
package/openapi.json CHANGED
@@ -10529,6 +10529,111 @@
10529
10529
  "x-struct": "Elixir.HablalaApiWeb.Schemas.PresignResult",
10530
10530
  "x-validate": null
10531
10531
  },
10532
+ "ProvisionMemberInput": {
10533
+ "description": "Datos para dar de alta un operador DIRECTO (sin invitación por email): queda miembro activo al instante y establece su contraseña por el link de set-password de la respuesta.",
10534
+ "properties": {
10535
+ "email": {
10536
+ "description": "Email del operador. Si ya existe un usuario con ese email, se reutiliza.",
10537
+ "format": "email",
10538
+ "type": "string",
10539
+ "x-struct": null,
10540
+ "x-validate": null
10541
+ },
10542
+ "role": {
10543
+ "description": "Nombre del rol a asignar (p. ej. `operator`). Opcional.",
10544
+ "nullable": true,
10545
+ "type": "string",
10546
+ "x-struct": null,
10547
+ "x-validate": null
10548
+ }
10549
+ },
10550
+ "required": [
10551
+ "email"
10552
+ ],
10553
+ "title": "ProvisionMemberInput",
10554
+ "type": "object",
10555
+ "x-struct": "Elixir.HablalaApiWeb.Schemas.ProvisionMemberInput",
10556
+ "x-validate": null
10557
+ },
10558
+ "ProvisionMemberRequest": {
10559
+ "properties": {
10560
+ "member": {
10561
+ "$ref": "#/components/schemas/ProvisionMemberInput"
10562
+ }
10563
+ },
10564
+ "required": [
10565
+ "member"
10566
+ ],
10567
+ "title": "ProvisionMemberRequest",
10568
+ "type": "object",
10569
+ "x-struct": "Elixir.HablalaApiWeb.Schemas.ProvisionMemberRequest",
10570
+ "x-validate": null
10571
+ },
10572
+ "ProvisionMemberResponse": {
10573
+ "description": "El operador dado de alta. `passwordSetupToken` es el token de un solo uso con el que la persona establece SU contraseña (nunca se le comparte una contraseña generada). `userCreated` indica si el usuario nació con esta alta o ya existía (en cuyo caso su contraseña no se toca).",
10574
+ "properties": {
10575
+ "data": {
10576
+ "properties": {
10577
+ "displayName": {
10578
+ "nullable": true,
10579
+ "type": "string",
10580
+ "x-struct": null,
10581
+ "x-validate": null
10582
+ },
10583
+ "email": {
10584
+ "nullable": true,
10585
+ "type": "string",
10586
+ "x-struct": null,
10587
+ "x-validate": null
10588
+ },
10589
+ "id": {
10590
+ "description": "Id de la membresía (`mbr_…`).",
10591
+ "type": "string",
10592
+ "x-struct": null,
10593
+ "x-validate": null
10594
+ },
10595
+ "passwordSetupToken": {
10596
+ "description": "Token de set-password (un solo uso). Entrégaselo a la persona para que fije su contraseña vía el flujo de reset. NO es una contraseña.",
10597
+ "type": "string",
10598
+ "x-struct": null,
10599
+ "x-validate": null
10600
+ },
10601
+ "roles": {
10602
+ "items": {
10603
+ "type": "string",
10604
+ "x-struct": null,
10605
+ "x-validate": null
10606
+ },
10607
+ "type": "array",
10608
+ "x-struct": null,
10609
+ "x-validate": null
10610
+ },
10611
+ "userCreated": {
10612
+ "description": "`true` si el usuario nació con esta alta; `false` si ya existía.",
10613
+ "type": "boolean",
10614
+ "x-struct": null,
10615
+ "x-validate": null
10616
+ }
10617
+ },
10618
+ "required": [
10619
+ "id",
10620
+ "roles",
10621
+ "passwordSetupToken",
10622
+ "userCreated"
10623
+ ],
10624
+ "type": "object",
10625
+ "x-struct": null,
10626
+ "x-validate": null
10627
+ }
10628
+ },
10629
+ "required": [
10630
+ "data"
10631
+ ],
10632
+ "title": "ProvisionMemberResponse",
10633
+ "type": "object",
10634
+ "x-struct": "Elixir.HablalaApiWeb.Schemas.ProvisionMemberResponse",
10635
+ "x-validate": null
10636
+ },
10532
10637
  "PublicOrganization": {
10533
10638
  "description": "Identidad PÚBLICA del tenant (la org del token) — el paralelo horizontal del `shop`/`brand` de Shopify. Deja al cliente pintar su chrome (nombre, logo) y conocer su `endUserObjectSlug` sin hardcodear la marca. NUNCA incluye la PII legal del negocio.",
10534
10639
  "properties": {
@@ -14528,6 +14633,61 @@
14528
14633
  ]
14529
14634
  }
14530
14635
  },
14636
+ "/v1/invitations": {
14637
+ "post": {
14638
+ "callbacks": {},
14639
+ "description": "Crea una invitación por **email** con un rol opcional (`{\"invitation\": {\"email\": \"…\", \"role_id\": \"role_…\"}}`). Al aceptarla, la persona queda como miembro de la organización y podrá iniciar sesión como operador (member session `mem_…`). La org sale del token (org-less), como el resto de la superficie de máquina. Requiere el permiso `invitations:create` (preset `team_admin`).",
14640
+ "operationId": "post /v1/invitations",
14641
+ "parameters": [],
14642
+ "requestBody": {
14643
+ "content": {
14644
+ "application/json": {
14645
+ "schema": {
14646
+ "$ref": "#/components/schemas/InvitationRequest"
14647
+ }
14648
+ }
14649
+ },
14650
+ "description": "Datos de la invitación",
14651
+ "required": false
14652
+ },
14653
+ "responses": {
14654
+ "201": {
14655
+ "content": {
14656
+ "application/json": {
14657
+ "schema": {
14658
+ "$ref": "#/components/schemas/InvitationResponse"
14659
+ }
14660
+ }
14661
+ },
14662
+ "description": "Invitación creada"
14663
+ },
14664
+ "403": {
14665
+ "content": {
14666
+ "application/json": {
14667
+ "schema": {
14668
+ "$ref": "#/components/schemas/Error"
14669
+ }
14670
+ }
14671
+ },
14672
+ "description": "Sin permiso"
14673
+ },
14674
+ "422": {
14675
+ "content": {
14676
+ "application/json": {
14677
+ "schema": {
14678
+ "$ref": "#/components/schemas/Error"
14679
+ }
14680
+ }
14681
+ },
14682
+ "description": "Error de validación"
14683
+ }
14684
+ },
14685
+ "summary": "Invitar a un operador por email (bootstrap del equipo, credencial de máquina)",
14686
+ "tags": [
14687
+ "invitations"
14688
+ ]
14689
+ }
14690
+ },
14531
14691
  "/v1/invitations/accept": {
14532
14692
  "post": {
14533
14693
  "callbacks": {},
@@ -16965,6 +17125,61 @@
16965
17125
  ]
16966
17126
  }
16967
17127
  },
17128
+ "/v1/members": {
17129
+ "post": {
17130
+ "callbacks": {},
17131
+ "description": "Crea al operador y su membresía ACTIVA al instante. Devuelve un `passwordSetupToken` para que la persona fije su contraseña (no se comparte ninguna contraseña generada). Requiere `organization_memberships:create` (preset `team_admin`).",
17132
+ "operationId": "post /v1/members",
17133
+ "parameters": [],
17134
+ "requestBody": {
17135
+ "content": {
17136
+ "application/json": {
17137
+ "schema": {
17138
+ "$ref": "#/components/schemas/ProvisionMemberRequest"
17139
+ }
17140
+ }
17141
+ },
17142
+ "description": "Datos del operador",
17143
+ "required": false
17144
+ },
17145
+ "responses": {
17146
+ "201": {
17147
+ "content": {
17148
+ "application/json": {
17149
+ "schema": {
17150
+ "$ref": "#/components/schemas/ProvisionMemberResponse"
17151
+ }
17152
+ }
17153
+ },
17154
+ "description": "Operador dado de alta"
17155
+ },
17156
+ "403": {
17157
+ "content": {
17158
+ "application/json": {
17159
+ "schema": {
17160
+ "$ref": "#/components/schemas/Error"
17161
+ }
17162
+ }
17163
+ },
17164
+ "description": "Sin permiso"
17165
+ },
17166
+ "422": {
17167
+ "content": {
17168
+ "application/json": {
17169
+ "schema": {
17170
+ "$ref": "#/components/schemas/Error"
17171
+ }
17172
+ }
17173
+ },
17174
+ "description": "Error de validación"
17175
+ }
17176
+ },
17177
+ "summary": "Dar de alta un operador directo (sin invitación)",
17178
+ "tags": [
17179
+ "members"
17180
+ ]
17181
+ }
17182
+ },
16968
17183
  "/v1/members/me": {
16969
17184
  "get": {
16970
17185
  "callbacks": {},
@@ -31818,6 +32033,39 @@
31818
32033
  ]
31819
32034
  }
31820
32035
  },
32036
+ "/v1/roles": {
32037
+ "get": {
32038
+ "callbacks": {},
32039
+ "operationId": "get /v1/roles",
32040
+ "parameters": [],
32041
+ "responses": {
32042
+ "200": {
32043
+ "content": {
32044
+ "application/json": {
32045
+ "schema": {
32046
+ "$ref": "#/components/schemas/RolesResponse"
32047
+ }
32048
+ }
32049
+ },
32050
+ "description": "Roles"
32051
+ },
32052
+ "403": {
32053
+ "content": {
32054
+ "application/json": {
32055
+ "schema": {
32056
+ "$ref": "#/components/schemas/Error"
32057
+ }
32058
+ }
32059
+ },
32060
+ "description": "Sin permiso"
32061
+ }
32062
+ },
32063
+ "summary": "Listar los roles de la organización (para asignar al invitar)",
32064
+ "tags": [
32065
+ "roles"
32066
+ ]
32067
+ }
32068
+ },
31821
32069
  "/v1/sso/callback": {
31822
32070
  "post": {
31823
32071
  "callbacks": {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hablala/api-contract",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "type": "module",
5
5
  "description": "Contrato tipado (OpenAPI → TypeScript) de la API de Hablalá — single source of truth generada desde el backend Elixir.",
6
6
  "license": "MIT",
@@ -47,8 +47,8 @@
47
47
  "openapi-typescript": "^7.4.0",
48
48
  "tsup": "^8.5.1",
49
49
  "typescript": "^5.7.2",
50
- "@hablala/typescript-config": "0.0.0",
51
- "@hablala/eslint-config": "0.0.0"
50
+ "@hablala/eslint-config": "0.0.0",
51
+ "@hablala/typescript-config": "0.0.0"
52
52
  },
53
53
  "scripts": {
54
54
  "generate": "openapi-typescript",