mitra-interactions-sdk 1.0.60-beta.4 → 1.0.60-beta.41

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
@@ -1,558 +1,433 @@
1
- # Mitra Interactions SDK
2
-
3
- SDK para interações com a plataforma Mitra via endpoints `/interactions/`.
4
-
5
- ## Permissões: `dev` vs `business`
6
-
7
- `userType` no token de login:
8
- - `dev` — chama tudo
9
- - `business` — chama apenas execução (SF, Data Loader, upload), auth e chat. Outras chamadas retornam **403**.
10
-
11
- > Não confundir com o pacote `mitra-business-sdk` (SDK separado, usado pelo agente IA).
12
-
13
- **Bloqueado para `business`:** CRUD REST (`*RecordMitra`), Profile Management (`*ProfileMitra`, `setProfile*Mitra`), `listProjectUsersMitra`, `manageUserAccessMitra`.
14
-
15
- > SF tipo JAVASCRIPT herda o `userType` do caller — se chamar funções bloqueadas, retorna 403 para business.
16
-
17
- ---
18
-
19
- ## Instalação
20
-
21
- ```bash
22
- npm install mitra-interactions-sdk
23
- # ou
24
- yarn add mitra-interactions-sdk
25
- # ou
26
- pnpm add mitra-interactions-sdk
27
- ```
28
-
29
- ## Configuração
30
-
31
- Antes de usar qualquer função, configure o SDK. O `token` é **opcional** — Server Functions públicas podem ser chamadas sem autenticação.
32
-
33
- > **Importante:** Quando usado, o token é um JWT de autenticação da plataforma Mitra. **Nunca deixe o token estático no código.** Utilize variáveis de ambiente para armazená-lo de forma segura.
34
-
35
- ```typescript
36
- import { configureSdkMitra } from 'mitra-interactions-sdk';
37
-
38
- // Configuração completa (com autenticação)
39
- const instance = configureSdkMitra({
40
- baseURL: process.env.MITRA_BASE_URL || 'https://api.mitra.com',
41
- token: process.env.MITRA_TOKEN!, // Opcional — necessário apenas para endpoints autenticados
42
- authUrl: 'https://coder.mitralab.io/sdk-auth/', // Opcional — necessário para login e token refresh
43
- projectId: 123, // Opcional — se informado, torna projectId opcional em TODOS os métodos
44
- integrationURL: 'https://api0.mitraecp.com:1003', // Opcional — necessário para integrações
45
- onTokenRefresh: (session) => { // Opcional — chamado quando o token é renovado automaticamente
46
- localStorage.setItem('mitra_session', JSON.stringify(session));
47
- }
48
- });
49
-
50
- // Configuração mínima (sem token — apenas para Server Functions públicas)
51
- const instance = configureSdkMitra({
52
- baseURL: 'https://api.mitra.com',
53
- projectId: 123
54
- });
55
- await instance.executeServerFunction({ serverFunctionId: 42 }); // OK — sem token
56
- ```
57
-
58
- > **`projectId` global:** Se você passar `projectId` no `configureSdkMitra`, ele será usado como fallback em **todos** os métodos do SDK. Assim, não é necessário passar `projectId` em cada chamada individual — basta configurar uma vez.
59
-
60
- `configureSdkMitra` retorna uma `MitraInstance` que também pode ser usada diretamente:
61
-
62
- ```typescript
63
- await instance.executeServerFunction({ serverFunctionId: 42 }); // projectId já vem do configureSdkMitra
64
- ```
65
-
66
- ## Autenticação (Login)
67
-
68
- Login via popup ou redirect seguro hospedado no domínio Mitra. Credenciais nunca passam pelo código do desenvolvedor. O SDK é **auto-configurado** após o login.
69
-
70
- > **Nota:** `authUrl` e `projectId` são **obrigatórios** para login. Porém, se já foram passados no `configureSdkMitra()`, não é necessário repeti-los — o SDK usa os valores configurados como fallback.
71
-
72
- ### Login via Popup (padrão)
73
-
74
- ```typescript
75
- import { loginMitra } from 'mitra-interactions-sdk';
76
-
77
- // Métodos disponíveis: 'email', 'google', 'microsoft', 'mitra'
78
- // Primeira vez — sem configureSdkMitra: authUrl e projectId são obrigatórios
79
- const result = await loginMitra('email', {
80
- authUrl: 'https://coder.mitralab.io/sdk-auth/',
81
- projectId: 123
82
- });
83
-
84
- // Se já chamou configureSdkMitra({ authUrl, projectId }), basta:
85
- const result = await loginMitra('google');
86
- const result = await loginMitra('microsoft');
87
-
88
- // result: { token, baseURL, integrationURL? }
89
- ```
90
-
91
- ### Login Completo (method 'mitra')
92
-
93
- Abre uma tela com todas as opções (Google, Microsoft, Email) e toggle entre Login/Cadastro.
94
-
95
- ```typescript
96
- await loginMitra('mitra', {
97
- authUrl: 'https://coder.mitralab.io/sdk-auth/',
98
- projectId: 123,
99
- title: 'Meu App' // Opcional — título exibido na tela de login (default: "Mitra")
100
- });
101
- ```
102
-
103
- ### Login via Redirect
104
-
105
- Navega o usuário para a página de auth. Após o login, redireciona de volta com token nos query params.
106
-
107
- ```typescript
108
- import { loginMitra } from 'mitra-interactions-sdk';
109
-
110
- // Iniciar login — o navegador navega para fora da página
111
- await loginMitra('google', {
112
- mode: 'redirect',
113
- returnTo: '/dashboard' // Opcional — URL de retorno após login (default: página atual). Só funciona com mode 'redirect'.
114
- });
115
- ```
116
-
117
- ### Fluxo de Criar Conta
118
-
119
- ```typescript
120
- // create funciona tanto em popup quanto redirect
121
- await loginMitra('email', { create: true });
122
-
123
- await loginMitra('mitra', {
124
- mode: 'redirect',
125
- create: true, // Abre direto no modo cadastro
126
- returnTo: '/onboarding',
127
- title: 'Meu App'
128
- });
129
- ```
130
-
131
- ### Token Refresh Automático
132
-
133
- Quando qualquer requisição retorna **403**, o SDK tenta renovar o token automaticamente via iframe invisível (usa o cookie de sessão do provider). Se o refresh funcionar, a requisição é retentada com o novo token — transparente para o desenvolvedor.
134
-
135
- O callback `onTokenRefresh` é chamado após renovação bem-sucedida:
136
-
137
- ```typescript
138
- configureSdkMitra({
139
- baseURL: '...',
140
- token: '...',
141
- authUrl: 'https://coder.mitralab.io/sdk-auth/',
142
- projectId: 123,
143
- onTokenRefresh: (session) => {
144
- // Atualiza o token salvo (ex: localStorage, store, etc.)
145
- localStorage.setItem('mitra_token', session.token);
146
- }
147
- });
148
- ```
149
-
150
- ### Login por Email (iframe silencioso)
151
-
152
- Para quem precisa montar sua **própria tela de login** (sem popup/redirect), o SDK oferece funções que fazem a autenticação via iframe invisível. As credenciais são enviadas ao HTML de auth via `postMessage` — sem CORS, sem expor a API.
153
-
154
- #### emailSignupMitra
155
-
156
- Cria conta. Após sucesso, o usuário recebe um código de verificação por email.
157
-
158
- ```typescript
159
- import { emailSignupMitra } from 'mitra-interactions-sdk';
160
-
161
- await emailSignupMitra({
162
- name: 'João Silva',
163
- email: 'joao@email.com',
164
- password: 'minhasenha123'
165
- });
166
- // Não retorna token — o próximo passo é verificar o código
167
- ```
168
-
169
- #### emailVerifyCodeMitra
170
-
171
- Verifica o código de 6 dígitos e faz login automático. Retorna `LoginResponse` e auto-configura o SDK.
172
-
173
- ```typescript
174
- import { emailVerifyCodeMitra } from 'mitra-interactions-sdk';
175
-
176
- const session = await emailVerifyCodeMitra({
177
- email: 'joao@email.com',
178
- code: '123456',
179
- password: 'minhasenha123' // Necessário para login automático após verificação
180
- });
181
- // session: { token, baseURL, integrationURL? }
182
- ```
183
-
184
- #### emailResendCodeMitra
185
-
186
- Reenvia o código de verificação para o email.
187
-
188
- ```typescript
189
- import { emailResendCodeMitra } from 'mitra-interactions-sdk';
190
-
191
- await emailResendCodeMitra({ email: 'joao@email.com' });
192
- ```
193
-
194
- #### emailLoginMitra
195
-
196
- Login direto com email e senha. Retorna `LoginResponse` e auto-configura o SDK.
197
-
198
- ```typescript
199
- import { emailLoginMitra } from 'mitra-interactions-sdk';
200
-
201
- const session = await emailLoginMitra({
202
- email: 'joao@email.com',
203
- password: 'minhasenha123'
204
- });
205
- // session: { token, baseURL, integrationURL? }
206
- ```
207
-
208
- #### Fluxo completo de signup com email
209
-
210
- ```typescript
211
- // 1. Criar conta
212
- await emailSignupMitra({ name: 'João', email, password });
213
-
214
- // 2. Usuário recebe código por email e digita na tela
215
- const session = await emailVerifyCodeMitra({ email, code: '123456', password });
216
-
217
- // 3. SDK já está configurado — pode chamar qualquer método
218
- await executeDbActionMitra({ dbActionId: 1 });
219
- ```
220
-
221
- > **Nota:** `authUrl` e `projectId` são opcionais em todas as funções de email se já foram configurados via `configureSdkMitra()`.
222
-
223
- ### Reset de Senha (esqueci minha senha)
224
-
225
- Endpoints públicos (sem token) para o fluxo de "esqueci minha senha":
226
-
227
- ```typescript
228
- import {
229
- sendPasswordResetCodeMitra,
230
- validatePasswordResetCodeMitra,
231
- resetPasswordMitra,
232
- emailLoginMitra
233
- } from 'mitra-interactions-sdk';
234
-
235
- // 1. Envia código de 6 dígitos por email
236
- await sendPasswordResetCodeMitra({ email });
237
-
238
- // 2. (opcional) Valida o código antes de pedir a senha nova
239
- await validatePasswordResetCodeMitra({ email, code: '123456' });
240
-
241
- // 3. Troca a senha
242
- await resetPasswordMitra({ email, code: '123456', newPassword: 'novaSenha' });
243
-
244
- // 4. Login com a nova senha
245
- await emailLoginMitra({ email, password: 'novaSenha' });
246
- ```
247
-
248
- > **Nota:** `projectId` é opcional se já configurado via `configureSdkMitra()`.
249
-
250
- ## Métodos Disponíveis
251
-
252
- ### executeServerFunctionMitra
253
-
254
- Executa uma Server Function de forma **síncrona** (timeout de 60s no backend). Retorna o resultado diretamente.
255
-
256
- ```typescript
257
- import { executeServerFunctionMitra } from 'mitra-interactions-sdk';
258
-
259
- const result = await executeServerFunctionMitra({
260
- projectId: 123,
261
- serverFunctionId: 101,
262
- input: { // Opcional - objeto de entrada para a função
263
- arg1: 'valor1'
264
- }
265
- });
266
- // result: { status, result: { executionId, executionStatus, output, logs, error, durationMs } }
267
- ```
268
-
269
- ### executeServerFunctionAsyncMitra
270
-
271
- Executa uma Server Function de forma **assíncrona**. Retorna um `executionId` imediatamente. Use `stopServerFunctionExecutionMitra` para parar ou `getServerFunctionExecutionMitra` (mitra-sdk) para consultar o resultado.
272
-
273
- ```typescript
274
- import { executeServerFunctionAsyncMitra } from 'mitra-interactions-sdk';
275
-
276
- const result = await executeServerFunctionAsyncMitra({
277
- projectId: 123,
278
- serverFunctionId: 101,
279
- input: { // Opcional - objeto de entrada para a função
280
- arg1: 'valor1'
281
- }
282
- });
283
- // result: { status, result: { executionId, executionStatus } }
284
- ```
285
-
286
- ### stopServerFunctionExecutionMitra
287
-
288
- Para a execução de uma Server Function em andamento.
289
-
290
- ```typescript
291
- import { stopServerFunctionExecutionMitra } from 'mitra-interactions-sdk';
292
-
293
- const result = await stopServerFunctionExecutionMitra({
294
- projectId: 123,
295
- executionId: 'exec-uuid-aqui'
296
- });
297
- // result: { status, result: { executionId, executionStatus: "CANCELLED" | "ALREADY_FINISHED" } }
298
- ```
299
-
300
- ### Public Server Functions (sem autenticação)
301
-
302
- Para Server Functions com `publicExecution = true`. Não requerem token.
303
-
304
- ```typescript
305
- import {
306
- executePublicServerFunctionMitra,
307
- executePublicServerFunctionAsyncMitra,
308
- getPublicServerFunctionExecutionMitra
309
- } from 'mitra-interactions-sdk';
310
-
311
- // Sync — retorna resultado inline (timeout 5min)
312
- const result = await executePublicServerFunctionMitra({
313
- projectId: 123,
314
- serverFunctionId: 49,
315
- input: { param1: 'value' }
316
- });
317
- // result: { executionId, status, output, logs, error, durationMs }
318
-
319
- // Async — retorna executionId imediatamente
320
- const { executionId } = await executePublicServerFunctionAsyncMitra({
321
- projectId: 123,
322
- serverFunctionId: 50,
323
- input: { heavyParam: true }
324
- });
325
-
326
- // Polling — consulta status/resultado
327
- const execution = await getPublicServerFunctionExecutionMitra({
328
- projectId: 123,
329
- executionId
330
- });
331
- // execution: { executionId, status, output, logs, error, durationMs }
332
- ```
333
-
334
- ### executeDataLoaderMitra
335
-
336
- Executa um Data Loader cadastrado no projeto.
337
-
338
- ```typescript
339
- import { executeDataLoaderMitra } from 'mitra-interactions-sdk';
340
-
341
- const result = await executeDataLoaderMitra({
342
- projectId: 123,
343
- dataLoaderId: 5,
344
- input: { mes: 1, ano: 2025 } // Opcional — parâmetros {{var}} da query
345
- });
346
- // result: { status, result: { dataLoaderId, executionLog: { timestamp, rowCount, query, status, fileSize?, duration? }, message } }
347
- ```
348
-
349
- ### uploadFilePublicMitra / uploadFileLoadableMitra
350
-
351
- Faz upload de um arquivo diretamente para a pasta PUBLIC ou LOADABLE do projeto. Usa `multipart/form-data`.
352
-
353
- ```typescript
354
- import { uploadFilePublicMitra, uploadFileLoadableMitra } from 'mitra-interactions-sdk';
355
-
356
- // Upload para PUBLIC (arquivo fica acessível publicamente via URL)
357
- const result = await uploadFilePublicMitra({
358
- projectId: 123,
359
- file: fileInput.files[0] // File ou Blob
360
- });
361
- // result: { status, result: { fileName, currentPath, publicUrl, message } }
362
-
363
- // Upload para LOADABLE (arquivo disponível para carga via Spark/ETL)
364
- const result2 = await uploadFileLoadableMitra({
365
- projectId: 123,
366
- file: myBlob
367
- });
368
- // result2: { status, result: { fileName, currentPath, publicUrl: null, message } }
369
- ```
370
-
371
- ### Dynamic Schema CRUD
372
-
373
- > 🔒 `userType=dev` only. Falha 403 para business. Em telas com business, envelopar em SF tipo SQL.
374
-
375
- CRUD completo em tabelas do projeto via Dynamic Schema (usa header `X-TenantID`).
376
-
377
- Todos os endpoints suportam o parâmetro opcional `jdbcConnectionConfigId` para operar em datasources adicionais (PostgreSQL, Oracle, SQL Server, etc.) ao invés do banco principal do tenant.
378
-
379
- - `listRecordsMitra(...)` → `ListRecordsResponse` `{ content, page, size, totalElements, totalPages }` - Lista registros com paginação
380
- - `getRecordMitra(...)` → `Record<string, any>` - Busca registro por ID
381
- - `createRecordMitra(...)` → `Record<string, any>` - Cria registro (201)
382
- - `updateRecordMitra(...)` → `Record<string, any>` - Atualiza registro (PUT)
383
- - `patchRecordMitra(...)` → `Record<string, any>` - Atualiza parcialmente (PATCH)
384
- - `deleteRecordMitra(...)` → `void` - Remove registro (204 No Content)
385
- - `createRecordsBatchMitra(...)` → `Record<string, any>[]` - Cria múltiplos registros (201)
386
-
387
- ```typescript
388
- import { listRecordsMitra, createRecordMitra, updateRecordMitra, deleteRecordMitra } from 'mitra-interactions-sdk';
389
-
390
- // Listar registros
391
- const result = await listRecordsMitra({
392
- projectId: 123,
393
- tableName: 'produtos',
394
- page: 0,
395
- size: 20
396
- });
397
-
398
- // Criar registro
399
- await createRecordMitra({
400
- projectId: 123,
401
- tableName: 'produtos',
402
- data: { nome: 'Produto A', preco: 99.90 }
403
- });
404
-
405
- // Atualizar registro
406
- await updateRecordMitra({
407
- projectId: 123,
408
- tableName: 'produtos',
409
- id: 1,
410
- data: { nome: 'Produto A Atualizado', preco: 89.90, version: 0 }
411
- });
412
-
413
- // Deletar registro
414
- await deleteRecordMitra({ projectId: 123, tableName: 'produtos', id: 1 });
415
-
416
- // Usando datasource adicional (jdbcConnectionConfigId)
417
- const result2 = await listRecordsMitra({
418
- projectId: 123,
419
- tableName: 'clientes',
420
- jdbcConnectionConfigId: 5
421
- });
422
- ```
423
-
424
- ### Profile Management
425
-
426
- > 🔒 `userType=dev` only. Falha 403 para business. Telas de perfis exigem guard de `userType`.
427
-
428
- Gerenciamento de perfis de acesso. Permite gestão de quem pode acessar quais recursos no projeto.
429
-
430
- #### CRUD de Perfis
431
-
432
- - `listProfilesMitra({ projectId? })` → `ListProfilesResponse` - Lista todos os perfis do projeto
433
- - `getProfileDetailsMitra({ projectId?, profileId })` → `GetProfileDetailsResponse` - Detalhes de um perfil (usuários, tabelas, actions, screens, server functions)
434
- - `createProfileMitra({ projectId?, name, color?, homeScreenId? })` → `CreateProfileResponse` - Cria um novo perfil
435
- - `updateProfileMitra({ projectId?, profileId, name?, color?, homeScreenId? })` → `UpdateProfileResponse` - Atualiza um perfil existente
436
- - `deleteProfileMitra({ projectId?, profileId })` → `DeleteProfileResponse` - Deleta um perfil
437
-
438
- ```typescript
439
- import { listProfilesMitra, createProfileMitra, getProfileDetailsMitra } from 'mitra-interactions-sdk';
440
-
441
- // Listar perfis
442
- const profiles = await listProfilesMitra({ projectId: 123 });
443
- // { status, projectId, result: [{ id, name, color, homeScreenId }] }
444
-
445
- // Criar perfil
446
- const created = await createProfileMitra({ projectId: 123, name: 'Vendedores', color: '#FF5733' });
447
- // { status, result: { id, name, message } }
448
-
449
- // Detalhes do perfil
450
- const details = await getProfileDetailsMitra({ projectId: 123, profileId: 1 });
451
- // { status, projectId, result: { id, name, users, selectTables, dmlTables, actions, screens, serverFunctions } }
452
- ```
453
-
454
- #### Permissões de Perfil
455
-
456
- Define quais recursos cada perfil pode acessar. Todas substituem a lista atual (não fazem append).
457
-
458
- - `setProfileUsersMitra({ projectId?, profileId, userIds })` - Define os usuários do perfil
459
- - `setProfileSelectTablesMitra({ projectId?, profileId, jdbcConnectionConfigId?, tables })` - Define tabelas SELECT permitidas
460
- - `setProfileDmlTablesMitra({ projectId?, profileId, jdbcConnectionConfigId?, tables })` - Define tabelas DML permitidas
461
- - `setProfileActionsMitra({ projectId?, profileId, actionIds })` - Define actions permitidas
462
- - `setProfileScreensMitra({ projectId?, profileId, screenIds })` - Define screens permitidas
463
- - `setProfileServerFunctionsMitra({ projectId?, profileId, serverFunctionIds })` - Define server functions permitidas
464
-
465
- ```typescript
466
- import { setProfileUsersMitra, setProfileSelectTablesMitra, setProfileServerFunctionsMitra } from 'mitra-interactions-sdk';
467
-
468
- // Definir usuários do perfil
469
- await setProfileUsersMitra({ projectId: 123, profileId: 1, userIds: [10, 20, 30] });
470
-
471
- // Definir tabelas SELECT
472
- await setProfileSelectTablesMitra({
473
- projectId: 123,
474
- profileId: 1,
475
- jdbcConnectionConfigId: 1, // Opcional — ID da conexão JDBC (default: banco principal)
476
- tables: [
477
- { tableName: 'clientes' },
478
- { tableName: 'pedidos' }
479
- ]
480
- });
481
-
482
- // Definir server functions
483
- await setProfileServerFunctionsMitra({ projectId: 123, profileId: 1, serverFunctionIds: [5, 8, 12] });
484
- ```
485
-
486
- ## Tipos TypeScript
487
-
488
- Todos os tipos estão incluídos:
489
-
490
- ```typescript
491
- import type {
492
- MitraConfig,
493
- // Login
494
- LoginOptions,
495
- LoginResponse,
496
- // Email Auth
497
- EmailSignupOptions,
498
- EmailLoginOptions,
499
- EmailVerifyCodeOptions,
500
- EmailResendCodeOptions,
501
- // Options
502
- ExecuteServerFunctionOptions,
503
- ExecuteServerFunctionAsyncOptions,
504
- UploadFileOptions,
505
- StopServerFunctionExecutionOptions,
506
- ListRecordsOptions,
507
- GetRecordOptions,
508
- CreateRecordOptions,
509
- UpdateRecordOptions,
510
- PatchRecordOptions,
511
- DeleteRecordOptions,
512
- CreateRecordsBatchOptions,
513
- // Responses
514
- ExecuteServerFunctionResponse,
515
- ExecuteServerFunctionAsyncResponse,
516
- UploadFileResponse,
517
- StopServerFunctionExecutionResponse,
518
- ListRecordsResponse,
519
- // Profile Management
520
- ListProfilesOptions,
521
- ListProfilesResponse,
522
- GetProfileDetailsOptions,
523
- GetProfileDetailsResponse,
524
- CreateProfileOptions,
525
- CreateProfileResponse,
526
- UpdateProfileOptions,
527
- UpdateProfileResponse,
528
- DeleteProfileOptions,
529
- DeleteProfileResponse,
530
- SetProfileUsersOptions,
531
- SetProfileSelectTablesOptions,
532
- SetProfileDmlTablesOptions,
533
- SetProfileActionsOptions,
534
- SetProfileScreensOptions,
535
- SetProfileServerFunctionsOptions,
536
- ProfileTableRef,
537
- SetProfilePermissionResponse
538
- } from 'mitra-interactions-sdk';
539
- ```
540
-
541
- ## Tratamento de Erros
542
-
543
- ```typescript
544
- try {
545
- const result = await executeDbActionMitra({
546
- projectId: 123,
547
- dbActionId: 456
548
- });
549
- } catch (error) {
550
- console.log('Erro:', error.message);
551
- console.log('Status:', error.status);
552
- console.log('Detalhes:', error.details);
553
- }
554
- ```
555
-
556
- ## Licença
557
-
558
- MIT
1
+ # Mitra Interactions SDK
2
+
3
+ SDK para interações com a plataforma Mitra via endpoints `/interactions/`.
4
+
5
+ ## Permissões: `dev` vs `business`
6
+
7
+ `userType` no token de login:
8
+ - `dev` — chama tudo
9
+ - `business` — chama apenas execução (SF), auth SSO e integrações. Outras chamadas retornam **403**.
10
+
11
+ > Não confundir com o pacote `mitra-business-sdk` (SDK separado, usado pelo agente IA).
12
+
13
+ **Bloqueado para `business`:** CRUD REST (`*RecordMitra`).
14
+
15
+ > SF tipo JAVASCRIPT herda o `userType` do caller — se chamar funções bloqueadas, retorna 403 para business.
16
+
17
+ ---
18
+
19
+ ## Instalação
20
+
21
+ ```bash
22
+ npm install mitra-interactions-sdk
23
+ # ou
24
+ yarn add mitra-interactions-sdk
25
+ # ou
26
+ pnpm add mitra-interactions-sdk
27
+ ```
28
+
29
+ ## Configuração
30
+
31
+ Antes de usar qualquer função, configure o SDK. O `token` é **opcional** — Server Functions públicas podem ser chamadas sem autenticação.
32
+
33
+ > **Importante:** Quando usado, o token é um JWT de autenticação da plataforma Mitra. **Nunca deixe o token estático no código.** Utilize variáveis de ambiente para armazená-lo de forma segura.
34
+
35
+ ```typescript
36
+ import { configureSdkMitra } from 'mitra-interactions-sdk';
37
+
38
+ // Configuração completa (com autenticação)
39
+ const instance = configureSdkMitra({
40
+ baseURL: process.env.MITRA_BASE_URL || 'https://api.mitra.com',
41
+ token: process.env.MITRA_TOKEN!, // Opcional — necessário apenas para endpoints autenticados
42
+ authUrl: 'https://coder.mitralab.io/sdk-auth/', // Opcional — necessário para login e token refresh
43
+ projectId: 123, // Opcional — se informado, torna projectId opcional em TODOS os métodos
44
+ integrationURL: 'https://api0.mitraecp.com:1003', // Opcional — necessário para integrações
45
+ onTokenRefresh: (session) => { // Opcional — chamado quando o token é renovado automaticamente
46
+ localStorage.setItem('mitra_session', JSON.stringify(session));
47
+ }
48
+ });
49
+
50
+ // Configuração mínima (sem token — apenas para Server Functions públicas)
51
+ const instance = configureSdkMitra({
52
+ baseURL: 'https://api.mitra.com',
53
+ projectId: 123
54
+ });
55
+ await instance.executeServerFunction({ serverFunctionId: 42 }); // OK — sem token
56
+ ```
57
+
58
+ > **`projectId` global:** Se você passar `projectId` no `configureSdkMitra`, ele será usado como fallback em **todos** os métodos do SDK. Assim, não é necessário passar `projectId` em cada chamada individual — basta configurar uma vez.
59
+
60
+ `configureSdkMitra` retorna uma `MitraInstance` que também pode ser usada diretamente:
61
+
62
+ ```typescript
63
+ await instance.executeServerFunction({ serverFunctionId: 42 }); // projectId já vem do configureSdkMitra
64
+ ```
65
+
66
+ ## Autenticação (Login)
67
+
68
+ Login via popup ou redirect seguro hospedado no domínio Mitra. Credenciais nunca passam pelo código do desenvolvedor. O SDK é **auto-configurado** após o login.
69
+
70
+ > **Nota:** `authUrl` e `projectId` são **obrigatórios** para login. Porém, se já foram passados no `configureSdkMitra()`, não é necessário repeti-los — o SDK usa os valores configurados como fallback.
71
+
72
+ ### Login via Popup (padrão)
73
+
74
+ ```typescript
75
+ import { loginWithGoogleMitra, loginWithMicrosoftMitra } from 'mitra-interactions-sdk';
76
+
77
+ // Primeira vez — sem configureSdkMitra: authUrl e projectId são obrigatórios
78
+ const result = await loginWithGoogleMitra({
79
+ authUrl: 'https://stg.mitralab.io/legacy',
80
+ projectId: 'uuid-do-projeto'
81
+ });
82
+
83
+ // Se já chamou configureSdkMitra({ authUrl, projectId }), basta:
84
+ const result = await loginWithGoogleMitra();
85
+ const result = await loginWithMicrosoftMitra();
86
+
87
+ // result: { token, baseURL, refreshToken }
88
+ ```
89
+
90
+ ### Login via Redirect (mobile)
91
+
92
+ No celular o popup vira aba — use `mode: 'redirect'`: a página de auth navega de volta pro app com `#codeMitra`/`#stateMitra` no fragment, e o app conclui com `exchangeSsoCodeMitra`.
93
+
94
+ ```typescript
95
+ import { loginWithGoogleMitra, exchangeSsoCodeMitra } from 'mitra-interactions-sdk';
96
+
97
+ // 1. Iniciar login — o navegador navega para fora da página
98
+ await loginWithGoogleMitra({ mode: 'redirect' });
99
+
100
+ // 2. No boot do app, se houver #codeMitra/#stateMitra no fragment:
101
+ const session = await exchangeSsoCodeMitra({ code, state });
102
+ // A SDK valida o nonce (anti-CSRF), troca o code no BFF e configura o SDK.
103
+ ```
104
+
105
+ ### Token Refresh Automático
106
+
107
+ Quando qualquer requisição retorna **403**, o SDK tenta renovar o token automaticamente via iframe invisível (usa o cookie de sessão do provider). Se o refresh funcionar, a requisição é retentada com o novo token — transparente para o desenvolvedor.
108
+
109
+ O callback `onTokenRefresh` é chamado após renovação bem-sucedida:
110
+
111
+ ```typescript
112
+ configureSdkMitra({
113
+ baseURL: '...',
114
+ token: '...',
115
+ authUrl: 'https://coder.mitralab.io/sdk-auth/',
116
+ projectId: 123,
117
+ onTokenRefresh: (session) => {
118
+ // Atualiza o token salvo (ex: localStorage, store, etc.)
119
+ localStorage.setItem('mitra_token', session.token);
120
+ }
121
+ });
122
+ ```
123
+
124
+ ## Métodos Disponíveis
125
+
126
+ ### executeServerFunctionMitra
127
+
128
+ Executa uma Server Function de forma **síncrona** (timeout de 60s no backend). Retorna o resultado diretamente.
129
+
130
+ ```typescript
131
+ import { executeServerFunctionMitra } from 'mitra-interactions-sdk';
132
+
133
+ const result = await executeServerFunctionMitra({
134
+ projectId: 123,
135
+ serverFunctionId: 101,
136
+ input: { // Opcional - objeto de entrada para a função
137
+ arg1: 'valor1'
138
+ }
139
+ });
140
+ // result: { status, result: { executionId, executionStatus, output, logs, error, durationMs } }
141
+ ```
142
+
143
+ ### executeServerFunctionAsyncMitra
144
+
145
+ Executa uma Server Function de forma **assíncrona**. Retorna um `executionId` imediatamente. Use `stopServerFunctionExecutionMitra` para parar ou `getServerFunctionExecutionMitra` (mitra-sdk) para consultar o resultado.
146
+
147
+ ```typescript
148
+ import { executeServerFunctionAsyncMitra } from 'mitra-interactions-sdk';
149
+
150
+ const result = await executeServerFunctionAsyncMitra({
151
+ projectId: 123,
152
+ serverFunctionId: 101,
153
+ input: { // Opcional - objeto de entrada para a função
154
+ arg1: 'valor1'
155
+ }
156
+ });
157
+ // result: { status, result: { executionId, executionStatus } }
158
+ ```
159
+
160
+ ### stopServerFunctionExecutionMitra
161
+
162
+ Para a execução de uma Server Function em andamento.
163
+
164
+ ```typescript
165
+ import { stopServerFunctionExecutionMitra } from 'mitra-interactions-sdk';
166
+
167
+ const result = await stopServerFunctionExecutionMitra({
168
+ projectId: 123,
169
+ executionId: 'exec-uuid-aqui'
170
+ });
171
+ // result: { status, result: { executionId, executionStatus: "CANCELLED" | "ALREADY_FINISHED" } }
172
+ ```
173
+
174
+ ### Server Functions Públicas (sem autenticação)
175
+
176
+ A SF deve ter `publicExecution = true` (via `togglePublicExecutionMitra` do mitra-sdk). Não exigem token.
177
+
178
+ ```typescript
179
+ import {
180
+ executePublicServerFunctionMitra,
181
+ executePublicServerFunctionAsyncMitra,
182
+ getPublicServerFunctionExecutionMitra
183
+ } from 'mitra-interactions-sdk';
184
+
185
+ // Síncrona (timeout 5min)
186
+ const res = await executePublicServerFunctionMitra({ projectId, serverFunctionId, input: { x: 1 } });
187
+ // { executionId, status, output, logs, error, durationMs }
188
+
189
+ // Assíncrona + polling
190
+ const async1 = await executePublicServerFunctionAsyncMitra({ projectId, serverFunctionId });
191
+ const status = await getPublicServerFunctionExecutionMitra({ projectId, executionId: async1.executionId });
192
+ ```
193
+
194
+ ### Dynamic Schema CRUD
195
+
196
+ > 🔒 `userType=dev` only. Falha 403 para business. Em telas com business, envelopar em SF tipo SQL.
197
+
198
+ CRUD completo em tabelas do projeto via Dynamic Schema (usa header `X-TenantID`).
199
+
200
+ Todos os endpoints suportam o parâmetro opcional `jdbcConnectionConfigId` para operar em datasources adicionais (PostgreSQL, Oracle, SQL Server, etc.) ao invés do banco principal do tenant.
201
+
202
+ - `listRecordsMitra(...)` → `ListRecordsResponse` `{ content, page, size, totalElements, totalPages }` - Lista registros com paginação
203
+ - `getRecordMitra(...)` → `Record<string, any>` - Busca registro por ID
204
+ - `createRecordMitra(...)` → `Record<string, any>` - Cria registro (201)
205
+ - `updateRecordMitra(...)` → `Record<string, any>` - Atualiza registro (PUT)
206
+ - `patchRecordMitra(...)` → `Record<string, any>` - Atualiza parcialmente (PATCH)
207
+ - `deleteRecordMitra(...)` → `void` - Remove registro (204 No Content)
208
+ - `createRecordsBatchMitra(...)` → `Record<string, any>[]` - Cria múltiplos registros (201)
209
+
210
+ ```typescript
211
+ import { listRecordsMitra, createRecordMitra, updateRecordMitra, deleteRecordMitra } from 'mitra-interactions-sdk';
212
+
213
+ // Listar registros
214
+ const result = await listRecordsMitra({
215
+ projectId: 123,
216
+ tableName: 'produtos',
217
+ page: 0,
218
+ size: 20
219
+ });
220
+
221
+ // Criar registro
222
+ await createRecordMitra({
223
+ projectId: 123,
224
+ tableName: 'produtos',
225
+ data: { nome: 'Produto A', preco: 99.90 }
226
+ });
227
+
228
+ // Atualizar registro
229
+ await updateRecordMitra({
230
+ projectId: 123,
231
+ tableName: 'produtos',
232
+ id: 1,
233
+ data: { nome: 'Produto A Atualizado', preco: 89.90, version: 0 }
234
+ });
235
+
236
+ // Deletar registro
237
+ await deleteRecordMitra({ projectId: 123, tableName: 'produtos', id: 1 });
238
+
239
+ // Usando datasource adicional (jdbcConnectionConfigId)
240
+ const result2 = await listRecordsMitra({
241
+ projectId: 123,
242
+ tableName: 'clientes',
243
+ jdbcConnectionConfigId: 5
244
+ });
245
+ ```
246
+
247
+ ## Agent Chat (copilot)
248
+
249
+ Chat com o agente de IA embarcado. **REST-first, tudo pela BFF no `baseURL` normal** (`/agentAiShortcut/*` — herda `fetchWithRefresh` e CORS): chats (`createChat`/`listChats`/`readChat`/`renameChat`/`deleteChat`), histórico (`listChatMessages`), credenciais e modelos. `projectId` obrigatório em todas (opcional na chamada se veio do `configureSdkMitra`). **Só o prompt é streaming** — um WebSocket por task em `wss://{origin}/copilot/ws/tasks/{taskId}?token=JWT`, aberto pela SDK quando a conversa começa (WS não passa por preflight de CORS).
250
+
251
+ Precisa de `token` e `baseURL` configurados (o login já deixa pronto). O transporte do prompt aceita `transport: 'ws' | 'http'` — `'ws'` é o default; `'http'` é **funcional**: `POST /copilot/api/v1/tasks/{id}/inputs` + SSE em `/events` via fetch, com a MESMA paridade de eventos do WS (pra ambientes onde WebSocket não rola, ex.: serverless).
252
+
253
+ ### Gerenciar os chats — `manageAgentChatMitra`
254
+
255
+ Tudo HTTP: listar (com filtros), renomear e deletar (= arquivar).
256
+
257
+ ```typescript
258
+ import { manageAgentChatMitra } from 'mitra-interactions-sdk';
259
+
260
+ const chats = await manageAgentChatMitra({ action: 'list' }); // AgentChat[]
261
+ const doAgente = await manageAgentChatMitra({ action: 'list', agentId: 'uuid-do-agente' }); // só os chats de um agente business
262
+ const busca = await manageAgentChatMitra({ action: 'list', search: 'vendas', page: 0, size: 20 });
263
+ const renamed = await manageAgentChatMitra({ action: 'rename', taskId, name: 'Novo nome' });
264
+ const deleted = await manageAgentChatMitra({ action: 'delete', taskId }); // arquiva (some da lista default)
265
+ ```
266
+
267
+ - `action: 'list'` → `AgentChat[]` — `{ id, name, agentType, agentId, archived, createdAt, updatedAt }`. Filtros: `agentId?`, `archived?`, `search?`, `page?`, `size?`.
268
+ - `action: 'rename'` → `{ taskId, name }` (POST `/agentAiShortcut/renameChat`)
269
+ - `action: 'delete'` → `{ taskId, deleted }` (POST `/agentAiShortcut/deleteChat` — arquiva, o histórico não é destruído)
270
+
271
+ ### Abrir uma session — `getAgentTaskMitra`
272
+
273
+ Retorna uma `AgentTaskSession` que encapsula o ciclo de vida do chat. A task é criada via BFF (`POST /agentAiShortcut/createChat`) no primeiro `send()`; o WS da task conecta em seguida. Abrir a mesma `taskId` duas vezes devolve a **mesma** instância (cache).
274
+
275
+ ```typescript
276
+ import { getAgentTaskMitra } from 'mitra-interactions-sdk';
277
+
278
+ // Chat novo — SEMPRE com agentId (sessão sem agente não executa nada).
279
+ // taskId é preenchido no primeiro send() (evento taskCreated)
280
+ const session = getAgentTaskMitra({ create: true, agentId: 'uuid-do-agente', agentType: 'ANTHROPIC_CLAUDE_OPUS', name: 'Meu chat' });
281
+
282
+ // Chat existente
283
+ const existing = getAgentTaskMitra({ taskId: 'uuid-da-task' });
284
+ await existing.loadHistory({ limit: 50 });
285
+ ```
286
+
287
+ `getAgentTaskMitra({ create: true, agentType?, name?, agentId?, reasoningEffort?, transport? })` ou `getAgentTaskMitra({ taskId, transport? })`.
288
+
289
+ **Agente autônomo**: a autonomia é **propriedade do AGENTE** (`autonomous` em `createAgentMitra`/`updateAgentMitra`, no `mitra-sdk`) — não existe flag na criação do chat. Ao criar um chat contra um agente autônomo (`getAgentTaskMitra({ create: true, agentId })`), o copilot deriva a autonomia do agente e o chat já nasce **sem dono** (`user_id NULL` — a dona é o agente), usando a connection anexada ao agente como credencial. Exige auth `AGENT_WRITE` (chave de SF ou token de app EDIT) — usuário business comum não abre chat autônomo. Depois de criado, dirigir/listar é igual ao chat normal (`getAgentTaskMitra({ taskId })`, `send`, `manageAgentChatMitra({ list, agentId })`).
290
+
291
+ - `agentType` vem de `manageAgentCredentialMitra({ action: 'list_models' })` — ex.: `'ANTHROPIC_CLAUDE_OPUS'`, `'OPENAI_GPT5'`. Default: `'ANTHROPIC_CLAUDE_OPUS'`.
292
+ - **`agentId`**: id de um agente business (CRUD via `mitra-sdk`: `listAgentsMitra` e família). A sessão sobe com o system prompt do agente e um token escopado — as tools enxergam só as Server Functions dele. **Sem `agentId`: sessão business sem agente** — sem system prompt e sem acesso às Server Functions (as tools recusam); não há adoção automática de agente único. Na prática, sempre passe `agentId`.
293
+
294
+ #### Propriedades (somente leitura)
295
+
296
+ | Propriedade | Tipo | Descrição |
297
+ |-------------|------|-----------|
298
+ | `taskId` | `string \| null` | `null` até o primeiro `send()` num chat novo |
299
+ | `task` | `AgentChat \| null` | Metadados do chat |
300
+ | `isNew` | `boolean` | Se foi aberto via `{ create: true }` |
301
+ | `status` | `AgentTaskStatus` | `opening` · `idle` · `streaming` · `cancelled` · `error` · `closed` |
302
+ | `history` | `AgentTimelineItem[]` | Linha do tempo canônica — `{ id, kind: 'user' \| 'agent', text, at }` ou `{ id, kind: 'tool', tool: AgentToolEvent, at }` (tool já desempacotada, mesmo shape do evento do streaming) |
303
+ | `content` | `string` | Conteúdo acumulado do turno atual |
304
+ | `queue` | `QueuedItem[]` | Mensagens enfileiradas (enviadas enquanto streamava) |
305
+
306
+ #### Métodos
307
+
308
+ - `send(prompt, { reasoningEffort?, agentType? })` → `void` — dispara um turno (`message` no WS ou POST `/inputs`). Se já está streamando, **enfileira** (FIFO, máx 10; as opções viajam com o item). `reasoningEffort`: intensidade desta mensagem — valores válidos vêm das `reasoningOptions` do modelo em `list_models` (**nunca invente**; fora do registro = `INVALID_REASONING_EFFORT`); herda o default de `getAgentTaskMitra({ create, reasoningEffort })` quando omitido. `agentType`: troca o modelo nesta mensagem — **só dentro do mesmo harness** (Claude↔Codex em conversa iniciada = `HARNESS_SWITCH`).
309
+ - `cancel()` → `Promise<void>` — interrompe o turno atual (WS `interrupt`, safety net de 10s).
310
+ - `respondApproval(approved)` → `void` — responde um pedido de aprovação do agente (WS `approval_response`).
311
+ - `loadHistory({ limit? })` → `Promise<AgentTimelineItem[]>` — histórico persistido via REST, já no formato canônico da timeline (renderizou o streaming, renderizou o histórico).
312
+ - `editQueueItem(id, text)` / `removeQueueItem(id)` / `clearQueue()` — manipulam a fila.
313
+ - `on(event, handler)` → função de unsubscribe — assina eventos da session.
314
+ - `close()` — encerra a session, fecha o WS e libera os listeners.
315
+
316
+ #### Eventos (`session.on`)
317
+
318
+ `statusChange` · `historyLoaded` · `taskCreated` · `turnStart` · `delta` (`{ delta, kind: 'text' | 'thinking' }`) · `tool` (`{ tool, toolId?, input?, content?, phase: 'call' | 'result' }`) · `turnEnd` (`{ content }`) · `cancelled` · `queueChange` · `error` (`{ code?, error }`) · `raw` (eventos não mapeados do stream, ex.: `workspace`).
319
+
320
+ ```typescript
321
+ const session = getAgentTaskMitra({ create: true, agentId: 'uuid-do-agente' });
322
+
323
+ session.on('delta', ({ delta, kind }) => { if (kind === 'text') process.stdout.write(delta); });
324
+ session.on('tool', ({ tool, phase }) => console.log('🔧', phase, tool));
325
+ session.on('turnEnd', ({ content }) => console.log('\n✓ fim do turno'));
326
+ session.on('taskCreated', ({ task }) => console.log('chat criado:', task.id));
327
+ session.on('error', ({ error }) => console.error(error));
328
+
329
+ session.send('Analise estas vendas e gere um resumo');
330
+ ```
331
+
332
+ ### Credenciais do agente — `manageAgentCredentialMitra`
333
+
334
+ Função única, toda HTTP **via BFF** (`/agentAiShortcut/listProviders`, `saveCredential`, `oauthStart`...). Providers: `'anthropic'` e `'openai'`. API key via `save`/`remove` (ambos); **OAuth (`auth`/`connect`) é exclusivo do anthropic; device flow (`device_auth`/`device_poll`) é exclusivo do openai** — fluxo trocado falha rápido com erro claro.
335
+
336
+ **`projectId` é obrigatório** em todas as actions (opcional na chamada se já veio do `configureSdkMitra`) — é ele que define de qual app é a credencial; o BFF resolve `projectId → appId` e cunha o token de app.
337
+
338
+ > 🔒 Tokens/keys nunca voltam crus — o backend devolve só status, e-mail da conta e a key mascarada.
339
+
340
+ ```typescript
341
+ import { manageAgentCredentialMitra } from 'mitra-interactions-sdk';
342
+
343
+ // Status por provider (pra montar a UI de conexão)
344
+ const { providers } = await manageAgentCredentialMitra({ action: 'list_providers' });
345
+ // AgentCredentialStatus[]: { provider, connected, credentialType, accountEmail, maskedApiKey }
346
+
347
+ // Modelos selecionáveis → use o agentType em getAgentTaskMitra
348
+ const { models } = await manageAgentCredentialMitra({ action: 'list_models' });
349
+ // AgentModel[]: { model, name, provider, agentType, reasoningOptions }
350
+ // reasoningOptions = registro das intensidades válidas por modelo (variam por
351
+ // harness) — monte o seletor de reasoning a partir DAQUI, nunca hardcode
352
+
353
+ // API key
354
+ await manageAgentCredentialMitra({ action: 'save', target: 'openai', key: 'sk-...' });
355
+ await manageAgentCredentialMitra({ action: 'remove', target: 'anthropic' });
356
+ ```
357
+
358
+ OAuth (só Anthropic) — `auth` devolve o que mostrar, `connect` finaliza:
359
+
360
+ ```typescript
361
+ const { authUrl, state } = await manageAgentCredentialMitra({ action: 'auth', target: 'anthropic' });
362
+ // app abre authUrl; usuário autoriza e copia o código
363
+ const { connected, email } = await manageAgentCredentialMitra({ action: 'connect', target: 'anthropic', code, state });
364
+ ```
365
+
366
+ Device flow (só OpenAI) — mostre `userCode` + `verificationUri` e faça polling:
367
+
368
+ ```typescript
369
+ const { deviceAuthId, userCode, verificationUri, intervalSeconds } =
370
+ await manageAgentCredentialMitra({ action: 'device_auth', target: 'openai' });
371
+ // app mostra: "abra {verificationUri} e digite {userCode}"; depois, a cada intervalSeconds:
372
+ const { connected } = await manageAgentCredentialMitra({ action: 'device_poll', target: 'openai', deviceAuthId });
373
+ ```
374
+
375
+ ## Tipos TypeScript
376
+
377
+ Todos os tipos estão incluídos:
378
+
379
+ ```typescript
380
+ import type {
381
+ MitraConfig,
382
+ // Login
383
+ LoginOptions,
384
+ LoginResponse,
385
+ // Options
386
+ ExecuteServerFunctionOptions,
387
+ ExecuteServerFunctionAsyncOptions,
388
+ StopServerFunctionExecutionOptions,
389
+ ListRecordsOptions,
390
+ GetRecordOptions,
391
+ CreateRecordOptions,
392
+ UpdateRecordOptions,
393
+ PatchRecordOptions,
394
+ DeleteRecordOptions,
395
+ CreateRecordsBatchOptions,
396
+ // Responses
397
+ ExecuteServerFunctionResponse,
398
+ ExecuteServerFunctionAsyncResponse,
399
+ StopServerFunctionExecutionResponse,
400
+ ListRecordsResponse,
401
+ // Agent Chat
402
+ AgentChat,
403
+ AgentMessage,
404
+ AgentTaskSession,
405
+ AgentTaskStatus,
406
+ SendOptions,
407
+ ManageAgentChatOptions,
408
+ GetAgentTaskOptions,
409
+ // Agent Credentials
410
+ ManageAgentCredentialOptions,
411
+ ListAgentModelsResult,
412
+ ListAgentProvidersResult
413
+ } from 'mitra-interactions-sdk';
414
+ ```
415
+
416
+ ## Tratamento de Erros
417
+
418
+ ```typescript
419
+ try {
420
+ const result = await executeServerFunctionMitra({
421
+ projectId: 123,
422
+ serverFunctionId: 456
423
+ });
424
+ } catch (error) {
425
+ console.log('Erro:', error.message);
426
+ console.log('Status:', error.status);
427
+ console.log('Detalhes:', error.details);
428
+ }
429
+ ```
430
+
431
+ ## Licença
432
+
433
+ MIT