bzapper 0.7.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.
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bzapper
4
+ # Erro devolvido pela API do bZapper (ou de rede, em {NetworkError}).
5
+ #
6
+ # Toda resposta fora de 2xx vira um `Bzapper::Error` — ou a subclasse do status. **Use
7
+ # {#code} na sua lógica**: ele é estável (`instance_not_connected`, `insufficient_scope`…).
8
+ # O {#message} é o `message` do corpo — texto para humanos, traduzido conforme `locale:`, que
9
+ # pode mudar (sem corpo JSON, é o próprio {#code}). {#detailed_message} junta código, status,
10
+ # escopo exigido, `Retry-After` e `request_id` (é o que aparece num erro não tratado).
11
+ #
12
+ # Argumento inválido no seu código (chave vazia, parâmetro de caminho vazio/"."/"..") NÃO é
13
+ # `Bzapper::Error`: é `ArgumentError`/`TypeError`, na hora, sem requisição.
14
+ class Error < StandardError
15
+ # @return [String] código estável: `body.code`, senão `body.error`, senão `HTTP_<status>`
16
+ # (corpo não-JSON); `INVALID_RESPONSE` quando um 2xx chega com corpo que não é JSON;
17
+ # `NETWORK_ERROR` em falha de rede.
18
+ attr_reader :code
19
+ # @return [Integer] status HTTP (`0` em erro de rede).
20
+ attr_reader :status
21
+ # @return [String, nil] header `X-Request-Id` da resposta, senão o `X-Request-Id` que a SDK
22
+ # enviou. Informe-o ao suporte.
23
+ attr_reader :request_id
24
+ # @return [Integer, Float, nil] segundos do header `Retry-After` (só em 429).
25
+ attr_reader :retry_after
26
+ # @return [String, nil] escopo que faltou na chave (header `X-Required-Scope`, só em 403).
27
+ attr_reader :required_scope
28
+ # @return [String, nil] idioma da mensagem (`body.locale`), quando veio.
29
+ attr_reader :locale
30
+ # @return [Hash, String, nil] corpo da resposta decodificado, ou o texto cru se não é JSON.
31
+ attr_reader :body
32
+
33
+ def initialize(message = nil, code: nil, status: 0, request_id: nil, retry_after: nil,
34
+ required_scope: nil, locale: nil, body: nil)
35
+ @code = code
36
+ @status = status
37
+ @request_id = request_id
38
+ @retry_after = retry_after
39
+ @required_scope = required_scope
40
+ @locale = locale
41
+ @body = body
42
+ super(message || code || self.class.name)
43
+ end
44
+
45
+ # Mensagem completa: `code (HTTP status): message — escopo… [request_id=…]`.
46
+ # @return [String]
47
+ def detailed_message(highlight: false, **_options) # rubocop:disable Lint/UnusedMethodArgument
48
+ text = +"#{code} (HTTP #{status})"
49
+ text << ": #{message}" unless message == code
50
+ text << " — escopo exigido: #{required_scope}" if required_scope
51
+ text << " — tente de novo em #{retry_after}s" unless retry_after.nil?
52
+ text << " [request_id=#{request_id}]" if request_id
53
+ text
54
+ end
55
+
56
+ # Alias do padrão Berni (`status_code` nas SDKs Python/PHP).
57
+ # @return [Integer]
58
+ def status_code
59
+ status
60
+ end
61
+
62
+ def inspect
63
+ "#<#{self.class.name} code=#{code.inspect} status=#{status.inspect} " \
64
+ "request_id=#{request_id.inspect}>"
65
+ end
66
+
67
+ STATUS_CLASSES = {} # preenchido abaixo, depois das subclasses
68
+ private_constant :STATUS_CLASSES
69
+
70
+ # Classe de erro para um status HTTP (5xx → {ServerError}; sem classe própria → a base).
71
+ # @param status [Integer]
72
+ # @return [Class]
73
+ def self.class_for(status)
74
+ return STATUS_CLASSES[status] if STATUS_CLASSES.key?(status)
75
+ return ServerError if status >= 500 && status <= 599
76
+
77
+ Error
78
+ end
79
+ end
80
+
81
+ # Nome da base no padrão Berni (`BzapperError` nas outras SDKs). É a MESMA classe.
82
+ BzapperError = Error
83
+
84
+ # 401 — chave ausente, inválida ou revogada (`connect_revoked` numa conexão Connect encerrada).
85
+ class AuthenticationError < Error; end
86
+
87
+ # 403 — sem permissão: papel insuficiente ou escopo faltando na chave ({#required_scope}).
88
+ class PermissionDeniedError < Error; end
89
+
90
+ # 404 — o recurso não existe (ou não é deste projeto).
91
+ class NotFoundError < Error; end
92
+
93
+ # 409 — o estado atual impede a operação.
94
+ class ConflictError < Error; end
95
+
96
+ # 400 e 422 — corpo ou parâmetro inválido.
97
+ class ValidationError < Error; end
98
+
99
+ # 429 — limite de requisições; {#retry_after} diz quanto esperar.
100
+ class RateLimitError < Error; end
101
+
102
+ # 5xx — erro do lado da API. Informe o {#request_id}.
103
+ class ServerError < Error; end
104
+
105
+ # Falha de conexão ou timeout (`status == 0`, `code == "NETWORK_ERROR"`).
106
+ class NetworkError < Error
107
+ def initialize(message = nil, request_id: nil, **_ignored)
108
+ super(message || "NETWORK_ERROR", code: "NETWORK_ERROR", status: 0, request_id: request_id)
109
+ end
110
+ end
111
+
112
+ class Error
113
+ STATUS_CLASSES.merge!(
114
+ 400 => ValidationError,
115
+ 401 => AuthenticationError,
116
+ 403 => PermissionDeniedError,
117
+ 404 => NotFoundError,
118
+ 409 => ConflictError,
119
+ 422 => ValidationError,
120
+ 429 => RateLimitError
121
+ ).freeze
122
+ end
123
+
124
+ # Assinatura de webhook ausente ou inválida ({Webhook.construct_event}). Não processe o evento.
125
+ class SignatureError < StandardError; end
126
+ end
@@ -0,0 +1,394 @@
1
+ # frozen_string_literal: true
2
+
3
+ # GERADO por script/generate.rb a partir de packages/sdk/openapi.yaml — não edite à mão.
4
+
5
+ module Bzapper
6
+ module Resources
7
+ # Conta, perfil, chaves de API, marca, projetos e usuários — `client.accounts`.
8
+ class Accounts < Base
9
+ # List the tenant's API keys (without the raw key). `GET /keys`
10
+ #
11
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
12
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
13
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
14
+ def list_my_keys(timeout: nil)
15
+ request("GET", "/keys", timeout: timeout)
16
+ end
17
+
18
+ # Generate a tenant API key (raw key shown only once). Admin only — an agent key/user gets 403
19
+ # admin_required. `POST /keys`
20
+ #
21
+ # @param name [String, nil] (corpo)
22
+ # @param role [String, nil] (corpo) Role of the key/user (super_admin is via the admin token).
23
+ # @param idempotency_key [String, nil] chave de idempotência (senão a SDK gera uma).
24
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
25
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
26
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
27
+ def create_my_key(name: UNSET, role: UNSET, idempotency_key: nil, timeout: nil)
28
+ payload = compact(
29
+ "name" => name,
30
+ "role" => role
31
+ )
32
+ request("POST", "/keys", body: payload, idempotency_key: idempotency_key, timeout: timeout)
33
+ end
34
+
35
+ # Revoke a tenant API key. Admin only. `DELETE /keys/{id}`
36
+ #
37
+ # @param id [String] Instance ID (UUID).
38
+ # @param idempotency_key [String, nil] chave de idempotência (senão a SDK gera uma).
39
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
40
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
41
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
42
+ # @raise [ArgumentError] parâmetro de caminho vazio, "." ou "..".
43
+ def revoke_my_key(id, idempotency_key: nil, timeout: nil)
44
+ request("DELETE",
45
+ "/keys/#{segment(id, "id")}",
46
+ idempotency_key: idempotency_key,
47
+ timeout: timeout)
48
+ end
49
+
50
+ # Authenticated identity (+ profile when it's a user session). `GET /me`
51
+ #
52
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
53
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
54
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
55
+ def get_me(timeout: nil)
56
+ request("GET", "/me", timeout: timeout)
57
+ end
58
+
59
+ # Update the user profile (name/phone/job title). `PATCH /me`
60
+ #
61
+ # @param name [String, nil] (corpo)
62
+ # @param phone [String, nil] (corpo) Stored as +DDIdigits.
63
+ # @param job_title [String, nil] (corpo)
64
+ # @param locale [String, nil] (corpo) UI language to persist on the account (e.g. pt-BR). Empty
65
+ # = unchanged.
66
+ # @param idempotency_key [String, nil] chave de idempotência (senão a SDK gera uma).
67
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
68
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
69
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
70
+ def update_profile(name: UNSET, phone: UNSET, job_title: UNSET, locale: UNSET,
71
+ idempotency_key: nil, timeout: nil)
72
+ payload = compact(
73
+ "name" => name,
74
+ "phone" => phone,
75
+ "job_title" => job_title,
76
+ "locale" => locale
77
+ )
78
+ request("PATCH", "/me", body: payload, idempotency_key: idempotency_key, timeout: timeout)
79
+ end
80
+
81
+ # Shared identity of the numbers (brand kit + "About"). `GET /brand`
82
+ #
83
+ # Returns the tenant identity. Only `about` is applicable to the WhatsApp profile; each number's
84
+ # profile name and photo are set by the customer on their own phone when pairing the number
85
+ # (WhatsApp does not allow a linked device to change them).
86
+ #
87
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
88
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
89
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
90
+ def get_brand(timeout: nil)
91
+ request("GET", "/brand", timeout: timeout)
92
+ end
93
+
94
+ # Update the shared identity. `PUT /brand`
95
+ #
96
+ # @param about [String, nil] (corpo) "About"/status — applied to all numbers.
97
+ # @param display_name [String, nil] (corpo) Business name (kit).
98
+ # @param logo_url [String, nil] (corpo) Logo URL (kit).
99
+ # @param website [String, nil] (corpo)
100
+ # @param email [String, nil] (corpo)
101
+ # @param phone [String, nil] (corpo) Contact phone in E.164 (+DDIdigits).
102
+ # @param address [String, nil] (corpo)
103
+ # @param description [String, nil] (corpo)
104
+ # @param idempotency_key [String, nil] chave de idempotência (senão a SDK gera uma).
105
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
106
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
107
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
108
+ def set_brand(about: UNSET, display_name: UNSET, logo_url: UNSET, website: UNSET,
109
+ email: UNSET, phone: UNSET, address: UNSET, description: UNSET,
110
+ idempotency_key: nil, timeout: nil)
111
+ payload = compact(
112
+ "about" => about,
113
+ "display_name" => display_name,
114
+ "logo_url" => logo_url,
115
+ "website" => website,
116
+ "email" => email,
117
+ "phone" => phone,
118
+ "address" => address,
119
+ "description" => description
120
+ )
121
+ request("PUT", "/brand", body: payload, idempotency_key: idempotency_key, timeout: timeout)
122
+ end
123
+
124
+ # Apply the "About" to ALL connected numbers. `POST /brand/apply`
125
+ #
126
+ # Pushes the `about` (status message) to all of the tenant's connected numbers. Returns how many
127
+ # were applied, the skipped ones (disconnected) and the total.
128
+ #
129
+ # @param idempotency_key [String, nil] chave de idempotência (senão a SDK gera uma).
130
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
131
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
132
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
133
+ def apply_brand(idempotency_key: nil, timeout: nil)
134
+ request("POST", "/brand/apply", idempotency_key: idempotency_key, timeout: timeout)
135
+ end
136
+
137
+ # Upload the brand logo (multipart) → DO Spaces. `POST /brand/logo`
138
+ #
139
+ # @param file [String, IO, Pathname] conteúdo do arquivo (bytes), um IO ou o caminho no disco.
140
+ # @param filename [String, nil] nome do arquivo (padrão: o do caminho, senão "file").
141
+ # @param content_type [String, nil] tipo MIME (padrão: application/octet-stream).
142
+ # @param idempotency_key [String, nil] chave de idempotência (senão a SDK gera uma).
143
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
144
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
145
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
146
+ def upload_brand_logo(file:, filename: nil, content_type: nil, idempotency_key: nil,
147
+ timeout: nil)
148
+ request("POST",
149
+ "/brand/logo",
150
+ multipart: upload("file", file, filename, content_type),
151
+ idempotency_key: idempotency_key,
152
+ timeout: timeout)
153
+ end
154
+
155
+ # List the account's projects. `GET /projects`
156
+ #
157
+ # Projects isolate numbers, inbox, API keys and statistics. Each API key belongs to ONE project;
158
+ # in the dashboard, the active project goes in the `X-Project-Id` header.
159
+ #
160
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
161
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
162
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
163
+ def list_projects(timeout: nil)
164
+ request("GET", "/projects", timeout: timeout)
165
+ end
166
+
167
+ # Create a project (admin). `POST /projects`
168
+ #
169
+ # @param name [String] (corpo)
170
+ # @param api_mode [String, nil] (corpo) Rail of the project: UNOFFICIAL (QR-paired numbers) or
171
+ # OFFICIAL (WhatsApp Cloud API). Immutable after creation.
172
+ # @param idempotency_key [String, nil] chave de idempotência (senão a SDK gera uma).
173
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
174
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
175
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
176
+ def create_project(name:, api_mode: UNSET, idempotency_key: nil, timeout: nil)
177
+ payload = compact(
178
+ "name" => name,
179
+ "api_mode" => api_mode
180
+ )
181
+ request("POST",
182
+ "/projects",
183
+ body: payload,
184
+ idempotency_key: idempotency_key,
185
+ timeout: timeout)
186
+ end
187
+
188
+ # Number status per project (traffic light). `GET /projects/health`
189
+ #
190
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
191
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
192
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
193
+ def get_projects_health(timeout: nil)
194
+ request("GET", "/projects/health", timeout: timeout)
195
+ end
196
+
197
+ # Update a project (admin). `PATCH /projects/{id}`
198
+ #
199
+ # `api_mode` is immutable and is ignored here.
200
+ #
201
+ # @param id [String] Resource ID (UUID).
202
+ # @param name [String] (corpo)
203
+ # @param logo_url [String, nil] (corpo)
204
+ # @param color [String, nil] (corpo)
205
+ # @param idempotency_key [String, nil] chave de idempotência (senão a SDK gera uma).
206
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
207
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
208
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
209
+ # @raise [ArgumentError] parâmetro de caminho vazio, "." ou "..".
210
+ def update_project(id, name:, logo_url: UNSET, color: UNSET, idempotency_key: nil,
211
+ timeout: nil)
212
+ payload = compact(
213
+ "name" => name,
214
+ "logo_url" => logo_url,
215
+ "color" => color
216
+ )
217
+ request("PATCH",
218
+ "/projects/#{segment(id, "id")}",
219
+ body: payload,
220
+ idempotency_key: idempotency_key,
221
+ timeout: timeout)
222
+ end
223
+
224
+ # Delete a project (admin). `DELETE /projects/{id}`
225
+ #
226
+ # @param id [String] Resource ID (UUID).
227
+ # @param idempotency_key [String, nil] chave de idempotência (senão a SDK gera uma).
228
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
229
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
230
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
231
+ # @raise [ArgumentError] parâmetro de caminho vazio, "." ou "..".
232
+ def delete_project(id, idempotency_key: nil, timeout: nil)
233
+ request("DELETE",
234
+ "/projects/#{segment(id, "id")}",
235
+ idempotency_key: idempotency_key,
236
+ timeout: timeout)
237
+ end
238
+
239
+ # Identity of the numbers of a specific project. `GET /projects/{id}/brand`
240
+ #
241
+ # @param id [String] Resource ID (UUID).
242
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
243
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
244
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
245
+ # @raise [ArgumentError] parâmetro de caminho vazio, "." ou "..".
246
+ def get_project_brand(id, timeout: nil)
247
+ request("GET", "/projects/#{segment(id, "id")}/brand", timeout: timeout)
248
+ end
249
+
250
+ # Save the identity of a specific project's numbers (admin). `PUT /projects/{id}/brand`
251
+ #
252
+ # @param id [String] Resource ID (UUID).
253
+ # @param about [String, nil] (corpo) "About"/status — applied to all numbers.
254
+ # @param display_name [String, nil] (corpo) Business name (kit).
255
+ # @param logo_url [String, nil] (corpo) Logo URL (kit).
256
+ # @param website [String, nil] (corpo)
257
+ # @param email [String, nil] (corpo)
258
+ # @param phone [String, nil] (corpo) Contact phone in E.164 (+DDIdigits).
259
+ # @param address [String, nil] (corpo)
260
+ # @param description [String, nil] (corpo)
261
+ # @param idempotency_key [String, nil] chave de idempotência (senão a SDK gera uma).
262
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
263
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
264
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
265
+ # @raise [ArgumentError] parâmetro de caminho vazio, "." ou "..".
266
+ def set_project_brand(id, about: UNSET, display_name: UNSET, logo_url: UNSET, website: UNSET,
267
+ email: UNSET, phone: UNSET, address: UNSET, description: UNSET,
268
+ idempotency_key: nil, timeout: nil)
269
+ payload = compact(
270
+ "about" => about,
271
+ "display_name" => display_name,
272
+ "logo_url" => logo_url,
273
+ "website" => website,
274
+ "email" => email,
275
+ "phone" => phone,
276
+ "address" => address,
277
+ "description" => description
278
+ )
279
+ request("PUT",
280
+ "/projects/#{segment(id, "id")}/brand",
281
+ body: payload,
282
+ idempotency_key: idempotency_key,
283
+ timeout: timeout)
284
+ end
285
+
286
+ # Upload the project logo (multipart, PNG/JPEG/WebP up to 5 MB) — admin. `POST
287
+ # /projects/{id}/logo`
288
+ #
289
+ # @param id [String] Resource ID (UUID).
290
+ # @param file [String, IO, Pathname] conteúdo do arquivo (bytes), um IO ou o caminho no disco.
291
+ # @param filename [String, nil] nome do arquivo (padrão: o do caminho, senão "file").
292
+ # @param content_type [String, nil] tipo MIME (padrão: application/octet-stream).
293
+ # @param idempotency_key [String, nil] chave de idempotência (senão a SDK gera uma).
294
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
295
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
296
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
297
+ # @raise [ArgumentError] parâmetro de caminho vazio, "." ou "..".
298
+ def upload_project_logo(id, file:, filename: nil, content_type: nil, idempotency_key: nil,
299
+ timeout: nil)
300
+ request("POST",
301
+ "/projects/#{segment(id, "id")}/logo",
302
+ multipart: upload("file", file, filename, content_type),
303
+ idempotency_key: idempotency_key,
304
+ timeout: timeout)
305
+ end
306
+
307
+ # List the account's users. `GET /users`
308
+ #
309
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
310
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
311
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
312
+ def list_users(timeout: nil)
313
+ request("GET", "/users", timeout: timeout)
314
+ end
315
+
316
+ # Invite a user (admin). `POST /users`
317
+ #
318
+ # Creates the user in the account with the given role and sends a link to set the password.
319
+ #
320
+ # @param email [String] (corpo)
321
+ # @param name [String, nil] (corpo)
322
+ # @param role [String, nil] (corpo) agent = member (no billing)
323
+ # @param idempotency_key [String, nil] chave de idempotência (senão a SDK gera uma).
324
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
325
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
326
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
327
+ def invite_user(email:, name: UNSET, role: UNSET, idempotency_key: nil, timeout: nil)
328
+ payload = compact(
329
+ "email" => email,
330
+ "name" => name,
331
+ "role" => role
332
+ )
333
+ request("POST", "/users", body: payload, idempotency_key: idempotency_key, timeout: timeout)
334
+ end
335
+
336
+ # Change a user's role (admin). `PATCH /users/{id}`
337
+ #
338
+ # Demoting the last administrator of the account is refused (409 last_admin).
339
+ #
340
+ # @param id [String] Resource ID (UUID).
341
+ # @param role [String] (corpo) agent = member (no billing)
342
+ # @param idempotency_key [String, nil] chave de idempotência (senão a SDK gera uma).
343
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
344
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
345
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
346
+ # @raise [ArgumentError] parâmetro de caminho vazio, "." ou "..".
347
+ def update_user_role(id, role:, idempotency_key: nil, timeout: nil)
348
+ payload = compact(
349
+ "role" => role
350
+ )
351
+ request("PATCH",
352
+ "/users/#{segment(id, "id")}",
353
+ body: payload,
354
+ idempotency_key: idempotency_key,
355
+ timeout: timeout)
356
+ end
357
+
358
+ # Remove a user from the account (admin). `DELETE /users/{id}`
359
+ #
360
+ # You cannot remove yourself (409 self_remove) nor the last administrator (409 last_admin).
361
+ #
362
+ # @param id [String] Resource ID (UUID).
363
+ # @param idempotency_key [String, nil] chave de idempotência (senão a SDK gera uma).
364
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
365
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
366
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
367
+ # @raise [ArgumentError] parâmetro de caminho vazio, "." ou "..".
368
+ def remove_user(id, idempotency_key: nil, timeout: nil)
369
+ request("DELETE",
370
+ "/users/#{segment(id, "id")}",
371
+ idempotency_key: idempotency_key,
372
+ timeout: timeout)
373
+ end
374
+
375
+ # Rename the account (company name) — admin. `PATCH /account`
376
+ #
377
+ # @param name [String] (corpo) Company name.
378
+ # @param idempotency_key [String, nil] chave de idempotência (senão a SDK gera uma).
379
+ # @param timeout [Numeric, nil] segundos por tentativa (padrão: o do cliente).
380
+ # @return [Hash, Array, nil] o JSON da resposta, inteiro (nil em 204).
381
+ # @raise [Bzapper::Error] resposta fora de 2xx ou falha de rede.
382
+ def update_account(name:, idempotency_key: nil, timeout: nil)
383
+ payload = compact(
384
+ "name" => name
385
+ )
386
+ request("PATCH",
387
+ "/account",
388
+ body: payload,
389
+ idempotency_key: idempotency_key,
390
+ timeout: timeout)
391
+ end
392
+ end
393
+ end
394
+ end