funifier-mcp 0.2.25 → 0.2.26

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.
Files changed (61) hide show
  1. package/datasource-funifier-docs/knowledge/index.md +1 -1
  2. package/datasource-funifier-docs/knowledge/modules/folder.md +347 -68
  3. package/dist/core/api-client.d.ts +21 -1
  4. package/dist/core/api-client.d.ts.map +1 -1
  5. package/dist/core/api-client.js +154 -1
  6. package/dist/core/api-client.js.map +1 -1
  7. package/dist/core/constants.d.ts +14 -0
  8. package/dist/core/constants.d.ts.map +1 -1
  9. package/dist/core/constants.js +14 -0
  10. package/dist/core/constants.js.map +1 -1
  11. package/dist/core/types/Folder.d.ts +16 -0
  12. package/dist/core/types/Folder.d.ts.map +1 -0
  13. package/dist/core/types/Folder.js +3 -0
  14. package/dist/core/types/Folder.js.map +1 -0
  15. package/dist/core/types/FolderContent.d.ts +10 -0
  16. package/dist/core/types/FolderContent.d.ts.map +1 -0
  17. package/dist/core/types/FolderContent.js +3 -0
  18. package/dist/core/types/FolderContent.js.map +1 -0
  19. package/dist/core/types/FolderContentType.d.ts +10 -0
  20. package/dist/core/types/FolderContentType.d.ts.map +1 -0
  21. package/dist/core/types/FolderContentType.js +3 -0
  22. package/dist/core/types/FolderContentType.js.map +1 -0
  23. package/dist/core/types/FolderLog.d.ts +11 -0
  24. package/dist/core/types/FolderLog.d.ts.map +1 -0
  25. package/dist/core/types/FolderLog.js +3 -0
  26. package/dist/core/types/FolderLog.js.map +1 -0
  27. package/dist/core/types/index.d.ts +4 -0
  28. package/dist/core/types/index.d.ts.map +1 -1
  29. package/dist/core/types/index.js +4 -0
  30. package/dist/core/types/index.js.map +1 -1
  31. package/dist/mcp/bundle.js +101 -93
  32. package/dist/mcp/check-update.d.ts +2 -0
  33. package/dist/mcp/check-update.d.ts.map +1 -0
  34. package/dist/mcp/check-update.js +44 -0
  35. package/dist/mcp/check-update.js.map +1 -0
  36. package/dist/mcp/index.js +3 -0
  37. package/dist/mcp/index.js.map +1 -1
  38. package/dist/mcp/tools/_char-guard.js +1 -1
  39. package/dist/mcp/tools/_char-guard.js.map +1 -1
  40. package/dist/mcp/tools/_fetch-current.d.ts +1 -1
  41. package/dist/mcp/tools/_fetch-current.d.ts.map +1 -1
  42. package/dist/mcp/tools/_fetch-current.js +12 -0
  43. package/dist/mcp/tools/_fetch-current.js.map +1 -1
  44. package/dist/mcp/tools/delete.d.ts.map +1 -1
  45. package/dist/mcp/tools/delete.js +20 -0
  46. package/dist/mcp/tools/delete.js.map +1 -1
  47. package/dist/mcp/tools/folder.d.ts +4 -0
  48. package/dist/mcp/tools/folder.d.ts.map +1 -0
  49. package/dist/mcp/tools/folder.js +58 -0
  50. package/dist/mcp/tools/folder.js.map +1 -0
  51. package/dist/mcp/tools/index.d.ts.map +1 -1
  52. package/dist/mcp/tools/index.js +2 -0
  53. package/dist/mcp/tools/index.js.map +1 -1
  54. package/dist/mcp/tools/save.d.ts.map +1 -1
  55. package/dist/mcp/tools/save.js +12 -0
  56. package/dist/mcp/tools/save.js.map +1 -1
  57. package/dist/mcp/tools/save.test.js +191 -0
  58. package/dist/mcp/tools/save.test.js.map +1 -1
  59. package/package.json +1 -1
  60. package/datasource-funifier-docs/.search-index.json +0 -17318
  61. package/datasource-funifier-docs/.skills-map.json +0 -73
@@ -84,7 +84,7 @@ A Funifier funciona como um **backend de aplicações**. Independentemente do ti
84
84
  | Módulo | Ficheiro | Descrição | Quando usar |
85
85
  |--------|----------|-----------|-------------|
86
86
  | Auth | `modules/auth.md` | Autenticação e tokens | Gerar tokens de acesso; configurar API keys; autenticação OAuth |
87
- | Folder | `modules/folder.md` | Organização em pastas | Organizar módulos (ações, desafios, etc.) em pastas no Studio |
87
+ | Folder | `modules/folder.md` | Trilhas e cursos | Criar trilhas de aprendizagem e cursos; organizar conteúdos em hierarquia com monitoramento de progresso do jogador |
88
88
  | Backup | `modules/backup.md` | Backup e restauração | Criar backups da gamificação; restaurar configurações |
89
89
  | Compact | `modules/compact.md` | Compactação de dados | Compactar dados históricos para otimizar performance |
90
90
  | Staging | `modules/staging.md` | Ambiente de homologação | Testar configurações em ambiente separado antes de produção |
@@ -1,111 +1,390 @@
1
- # Folder (Pasta)
1
+ # Folder (Trilha / Curso)
2
2
 
3
3
  **Acesso Studio:** `/studio/folder`
4
- **API Endpoint:** `/v3/folder`
4
+ **API Base:** `/v3/folder`
5
5
 
6
6
  ## O que é
7
7
 
8
- Organização de conteúdos e monitoramento do progresso em cursos ou trilhas. Permite criar pastas virtuais para agrupar conteúdos como quizzes, desafios, materiais de estudo e jogos, facilitando o acompanhamento do progresso dos jogadores em jornadas de aprendizagem ou trilhas gamificadas.
8
+ Sistema de trilhas de aprendizagem e cursos. Permite criar hierarquias de pastas com conteúdos associados (quizzes, vídeos, textos, desafios), monitorar o progresso de cada jogador em cada nível da hierarquia, e desbloquear conteúdo condicionalmente com base no progresso anterior.
9
9
 
10
10
  ## Quando usar
11
11
 
12
- - Para estruturar cursos online
13
- - Para criar trilhas de capacitação
14
- - Para acompanhar progresso em treinamentos
15
- - Para organizar conteúdos em hierarquias (módulos aulas conteúdos)
12
+ - Para estruturar cursos com módulos e aulas
13
+ - Para criar trilhas de capacitação/treinamento
14
+ - Para acompanhar o progresso individual de jogadores em jornadas
15
+ - Para organizar conteúdos em hierarquias com controle de ordem e desbloqueio
16
16
 
17
- ## Checklist de Configuração no Studio
17
+ ## Collections MongoDB
18
18
 
19
- - [ ] Criar estrutura hierárquica de pastas
20
- - [ ] Definir títulos das pastas
21
- - [ ] Associar conteúdos às pastas (quizzes, desafios, textos)
22
- - [ ] Definir tipos de conteúdo (folder_content_type)
23
- - [ ] Configurar pasta-pai (parent) para hierarquia
19
+ | Collection | Descrição |
20
+ |------------|-----------|
21
+ | `folder` | Estrutura de pastas (raiz e sub-pastas) |
22
+ | `folder_content` | Vínculo entre pasta e item de conteúdo |
23
+ | `folder_content_type` | Schema de um tipo de conteúdo (video, text, quiz…) |
24
+ | `folder_log` | Histórico de progresso do jogador por item |
25
+
26
+ ---
27
+
28
+ ## Entidades
29
+
30
+ ### Folder
31
+
32
+ Representa uma pasta ou módulo da trilha.
33
+
34
+ | Campo | Tipo | Obrigatório | Descrição |
35
+ |-------|------|-------------|-----------|
36
+ | `_id` | string | Não (auto) | ID único |
37
+ | `title` | string | **Sim** | Nome da pasta |
38
+ | `type` | string | Não | Categoria da pasta (livre) |
39
+ | `parent` | string | Não | ID da pasta pai (ausente = raiz) |
40
+ | `position` | number | Não (default 0) | Ordem de exibição entre irmãos |
41
+ | `active` | boolean | Não (default true) | false = oculta da árvore |
42
+ | `unlock_policy` | UnlockPolicy | Não | Regra de desbloqueio condicional |
43
+ | `extra` | object | Não | Campos livres adicionais |
44
+
45
+ ### UnlockPolicy
46
+
47
+ Define quando uma pasta fica disponível para o jogador.
48
+
49
+ | Campo | Tipo | Valores | Descrição |
50
+ |-------|------|---------|-----------|
51
+ | `type` | string | `"progress"` | Único tipo suportado |
52
+ | `folder_ref` | string | `"prev"` ou ID | `"prev"` = pasta irmã anterior; ID = pasta específica |
53
+ | `min_percent` | number | 0–100 | Percentual mínimo exigido |
54
+
55
+ **Herança:** o servidor sobe na árvore até encontrar um `unlock_policy`. Se uma pasta não tem policy própria, herda do pai.
56
+
57
+ ### FolderContent
58
+
59
+ Vínculo entre uma pasta e um item de conteúdo.
60
+
61
+ | Campo | Tipo | Obrigatório | Descrição |
62
+ |-------|------|-------------|-----------|
63
+ | `_id` | string | Não (auto) | ID único |
64
+ | `type` | string | **Sim** | `_id` do `FolderContentType` |
65
+ | `content` | string | Condicional | `_id` do item real (apenas quando `input=repository`) |
66
+ | `parent` | string | **Sim** | `_id` da pasta pai |
67
+ | `title` | string | Não | Auto-populado do item real se omitido |
68
+ | `extra` | object | Não | Campos livres |
69
+ | `position` | number | Não (default 0) | Ordem de exibição |
70
+
71
+ ### FolderContentType
72
+
73
+ Define o schema de um tipo de conteúdo.
74
+
75
+ | Campo | Tipo | Obrigatório | Descrição |
76
+ |-------|------|-------------|-----------|
77
+ | `_id` | string | **Sim** | Identificador (ex: `"video"`, `"text"`, `"quiz"`) |
78
+ | `entity` | string | **Sim** | Nome da coleção MongoDB onde os dados reais ficam |
79
+ | `input` | string | **Sim** | `"repository"` ou `"formulary"` (ver abaixo) |
80
+ | `title` | string | Não | Label de exibição |
81
+ | `image` | string | Não | URL de ícone |
82
+ | `slug` | string | Não | Slug para URL |
83
+ | `attributes` | array | Não | Campos do formulário (quando `input=formulary`) |
84
+
85
+ **`input=repository`:** o conteúdo referencia um item já existente em outra coleção via `content`.
86
+ **`input=formulary`:** o conteúdo cria um novo item inline na coleção `entity`. ⚠️ Ao deletar o `FolderContent`, o dado real também é deletado.
87
+
88
+ ### FolderLog
89
+
90
+ Registo de progresso de um jogador em um conteúdo.
91
+
92
+ | Campo | Tipo | Obrigatório | Descrição |
93
+ |-------|------|-------------|-----------|
94
+ | `_id` | string | Não (auto) | ID único |
95
+ | `item` | string | **Sim** | `_id` do `FolderContent` |
96
+ | `player` | string | **Sim** | ID do jogador |
97
+ | `status` | string | Não | `"done"` para concluído |
98
+ | `percent` | number | Não | 0.0–100.0 |
99
+ | `started` | Date | Não (auto) | Preenchido automaticamente |
100
+ | `finished` | Date | Não (auto) | Preenchido quando concluído |
101
+ | `extra` | object | Não | Campos livres (ex: `date`) |
102
+
103
+ ### Inside (resposta de inside/progress)
104
+
105
+ Nó da árvore retornado por `POST /v3/folder/inside` e `POST /v3/folder/progress`.
106
+
107
+ | Campo | Tipo | Descrição |
108
+ |-------|------|-----------|
109
+ | `_id` | string | ID do nó |
110
+ | `folder` | boolean | `true`=pasta, `false`=conteúdo |
111
+ | `title` | string | Título |
112
+ | `type` | string | Tipo |
113
+ | `content` | string | ID do item real (apenas em conteúdos) |
114
+ | `items` | Inside[] | Filhos (sub-pastas e conteúdos), ordenados por `position` |
115
+ | `player` | string | ID do jogador (apenas em `progress`) |
116
+ | `total` | number | Total de conteúdos na sub-árvore (apenas em `progress`) |
117
+ | `done` | number | Conteúdos concluídos (apenas em `progress`) |
118
+ | `percent` | number | % de conclusão (apenas em `progress`) |
119
+ | `time` | Date | Data da última conclusão na sub-árvore |
120
+ | `is_unlocked` | boolean | Se a pasta está desbloqueada (null para conteúdos) |
121
+
122
+ ---
24
123
 
25
124
  ## API Endpoints
26
125
 
27
- ### Listar Pastas
28
- **Método:** GET
29
- **Endpoint:** `/v3/database/folder`
126
+ ### Folder
30
127
 
31
- ### Criar Pasta
32
- **Método:** POST
33
- **Endpoint:** `/v3/folder`
128
+ #### Criar Pasta
129
+ **POST** `/v3/folder`
130
+ ```json
131
+ { "title": "Módulo 1", "parent": "raiz_id", "position": 0 }
132
+ ```
133
+ Resposta: `Folder` criado com `_id` gerado.
134
+
135
+ #### Buscar Pasta
136
+ **GET** `/v3/folder/:id`
137
+
138
+ #### Listar Pastas
139
+ **GET** `/v3/database/folder`
140
+
141
+ #### Deletar Pasta ⚠️ CASCATA
142
+ **DELETE** `/v3/folder/:id`
143
+
144
+ > Remove recursivamente: sub-pastas, folder_content, folder_log, e — se `ContentType.input = "formulary"` — os dados reais na coleção `entity`. **Irreversível.**
145
+
146
+ #### Deletar por Query
147
+ **DELETE** `/v3/folder?q=parent:"<id>"`
34
148
 
35
- **Exemplo de Body:**
149
+ #### Reordenar Pasta
150
+ **GET** `/v3/folder/:id/move?direction=up` ou `direction=down`
151
+
152
+ #### Árvore Completa
153
+ **POST** `/v3/folder/inside`
154
+ ```json
155
+ { "folder": "<id>" }
156
+ ```
157
+ Retorna árvore `Inside` completa (pastas + conteúdos), ordenada por `position`.
158
+
159
+ #### Progresso do Jogador
160
+ **POST** `/v3/folder/progress`
161
+ ```json
162
+ { "folder": "<id>", "player": "<playerId>" }
163
+ ```
164
+ Retorna árvore `Inside` com `total`, `done`, `percent`, `time`, `is_unlocked` por nó. Também **dispara o trigger `folder_progress`**.
165
+
166
+ #### Breadcrumb
167
+ **POST** `/v3/folder/breadcrumb`
168
+ ```json
169
+ { "folder": "<id>" }
170
+ ```
171
+ Retorna array de `Folder` do raiz até o nó: `[root, ..., target]`.
172
+
173
+ ---
174
+
175
+ ### Folder Content
176
+
177
+ #### Adicionar Conteúdo
178
+ **POST** `/v3/folder/content`
179
+ ```json
180
+ { "type": "video", "content": "<video_id>", "parent": "<folder_id>" }
181
+ ```
182
+
183
+ #### Buscar Conteúdo
184
+ **GET** `/v3/folder/content/:id`
185
+
186
+ #### Buscar Dados Reais do Conteúdo
187
+ **GET** `/v3/folder/content/:id/data`
188
+ Retorna o objeto real da coleção `entity` associada ao `FolderContentType`.
189
+
190
+ #### Listar Conteúdos (com aggregate)
191
+ **POST** `/v3/folder/content/aggregate?folder=<id>&cascade=true&append_data=true`
192
+ Body: pipeline MongoDB opcional (array).
193
+ - `cascade=true`: inclui conteúdos de sub-pastas
194
+ - `append_data=true`: adiciona campo `data` com o objeto real de cada conteúdo
195
+
196
+ #### Listar Conteúdos Diretos
197
+ **GET** `/v3/database/folder_content`
198
+
199
+ #### Reordenar Conteúdo
200
+ **GET** `/v3/folder/content/:id/move?direction=up` ou `direction=down`
201
+
202
+ #### Deletar Conteúdo
203
+ **DELETE** `/v3/folder/content/:id`
204
+ > Se `ContentType.input = "formulary"`, também deleta o dado real. Deleta todos os `folder_log` do conteúdo.
205
+
206
+ #### Deletar por Query
207
+ **DELETE** `/v3/folder/content?q=parent:"<id>"`
208
+
209
+ ---
210
+
211
+ ### Folder Content Type
212
+
213
+ #### Criar / Atualizar Tipo
214
+ **PUT** `/v3/database/folder_content_type`
36
215
  ```json
37
216
  {
38
- "title": "CoreDrives",
39
- "parent": "D0MmmNf"
217
+ "_id": "video",
218
+ "entity": "video__c",
219
+ "input": "repository",
220
+ "title": "Vídeo"
40
221
  }
41
222
  ```
42
223
 
43
- ### Deletar Pasta
44
- **Método:** DELETE
45
- **Endpoint:** `/v3/folder/:id`
224
+ #### Listar Tipos
225
+ **GET** `/v3/database/folder_content_type`
226
+
227
+ ---
228
+
229
+ ### Folder Log
230
+
231
+ #### Registrar Progresso ⚠️ Via endpoint REST (não via database direto)
232
+ **POST** `/v3/folder/log`
233
+ ```json
234
+ { "item": "<content_id>", "player": "player123", "status": "done" }
235
+ ```
236
+ Ou com percentual parcial:
237
+ ```json
238
+ { "item": "<content_id>", "player": "player123", "percent": 60.0 }
239
+ ```
240
+
241
+ > **Importante:** use sempre `/v3/folder/log` para registrar progresso, nunca insira direto na collection `folder_log`. O endpoint contém lógica de negócio crítica (idempotência, cálculo de progresso, triggers).
242
+
243
+ #### Buscar Log
244
+ **GET** `/v3/folder/log/:id`
245
+
246
+ #### Deletar Log
247
+ **DELETE** `/v3/folder/log/:id`
248
+ Dispara `BEFORE_DELETE` e `AFTER_DELETE` em triggers de `folder_log`.
249
+
250
+ #### Listar Logs (consulta)
251
+ **GET** `/v3/database/folder_log`
252
+
253
+ ---
254
+
255
+ ## Comportamentos Críticos de Segurança
256
+
257
+ ### 1. DELETE em Cascata (deleteFolder)
258
+ `DELETE /v3/folder/:id` é uma operação destrutiva em cascata:
259
+ 1. Deleta todos os sub-folders recursivamente
260
+ 2. Deleta todos os `folder_content` da pasta
261
+ 3. Deleta todos os `folder_log` dos conteúdos
262
+ 4. Se `FolderContentType.input = "formulary"`: deleta o dado real na coleção `entity`
263
+
264
+ **⚠️ Sempre confirmar com o usuário antes de executar. Irreversível.**
265
+
266
+ ### 2. insertLog é Idempotente
267
+ O servidor busca log existente por `(player, item)` sem `finished`. Se encontrado, atualiza em vez de criar novo. Nunca gera duplicata para um conteúdo em andamento.
46
268
 
47
- ### Obter Breadcrumb
48
- **Método:** POST
49
- **Endpoint:** `/v3/folder/breadcrumb`
269
+ ### 3. Auto-Status
270
+ - `status: "done"` → `percent = 100.0` + `finished = now` (automático)
271
+ - `percent >= 100` → `status = "done"` + `finished = now` (automático)
50
272
 
51
- **Exemplo de Body:**
273
+ ### 4. Herança de unlock_policy
274
+ O servidor percorre a árvore para cima até encontrar um `unlock_policy`. Pastas sem policy própria herdam do pai.
275
+
276
+ ---
277
+
278
+ ## Trigger Events
279
+
280
+ ### Coleção `folder_log`
281
+ | Evento | Quando |
282
+ |--------|--------|
283
+ | `BEFORE_CREATE` | Antes de inserir/atualizar log |
284
+ | `AFTER_CREATE` | Após inserir/atualizar log |
285
+ | `BEFORE_DELETE` | Antes de deletar log |
286
+ | `AFTER_DELETE` | Após deletar log |
287
+
288
+ ### Coleção `folder_progress` (evento: `AFTER_CREATE`)
289
+ Disparado para **cada pasta no breadcrumb** (do mais próximo ao raiz) sempre que o progresso aumenta. Payload:
52
290
  ```json
53
291
  {
54
- "folder": "CD1"
292
+ "_id": "<folderId>",
293
+ "player": "<playerId>",
294
+ "folder": { "_id": "...", "title": "Módulo 1" },
295
+ "progress": { "percent": 60.0, "done": 3, "total": 5 },
296
+ "previous_percent": 40.0,
297
+ "current_percent": 60.0,
298
+ "time": "<timestamp>"
55
299
  }
56
300
  ```
57
301
 
58
- ### Listar Tipos de Conteúdo
59
- **Método:** GET
60
- **Endpoint:** `/v3/database/folder_content_type`
302
+ ---
303
+
304
+ ## Uso com MCP
305
+
306
+ | Operação | Tool | Parâmetros |
307
+ |---------|------|-----------|
308
+ | Criar/atualizar pasta | `funifier_save` | `type: "folder"` |
309
+ | Deletar pasta (cascata) | `funifier_delete` | `type: "folder"` |
310
+ | Adicionar conteúdo | `funifier_save` | `type: "folder-content"` |
311
+ | Deletar conteúdo | `funifier_delete` | `type: "folder-content"` |
312
+ | Definir tipo de conteúdo | `funifier_save` | `type: "folder-content-type"` |
313
+ | Registrar progresso | `funifier_save` | `type: "folder-log"` |
314
+ | Deletar log | `funifier_delete` | `type: "folder-log"` |
315
+ | Ver árvore completa | `funifier_folder` | `operation: "inside"` |
316
+ | Ver progresso do jogador | `funifier_folder` | `operation: "progress"` |
317
+ | Ver breadcrumb | `funifier_folder` | `operation: "breadcrumb"` |
318
+ | Consultar logs/conteúdos | `funifier_database` | `collection: "folder_log"` etc. |
61
319
 
62
- ### Criar/Atualizar Tipo de Conteúdo
63
- **Método:** PUT
64
- **Endpoint:** `/v3/database/folder_content_type`
320
+ ---
65
321
 
66
- **Exemplo de Body:**
322
+ ## Exemplo Completo: Criar Trilha de Vendas
323
+
324
+ ### 1. Criar pasta raiz
325
+ ```json
326
+ funifier_save type=folder
327
+ { "title": "Trilha de Vendas" }
328
+ ```
329
+
330
+ ### 2. Criar módulo dentro da trilha
67
331
  ```json
332
+ funifier_save type=folder
333
+ { "title": "Módulo 1 - Prospecção", "parent": "<trilha_id>", "position": 0 }
334
+ ```
335
+
336
+ ### 3. Criar segundo módulo com unlock_policy
337
+ ```json
338
+ funifier_save type=folder
68
339
  {
69
- "_id": "text",
70
- "input": "formulary",
71
- "form": [
72
- { "name": "title", "type": "string", "title": "Title" },
73
- { "name": "content", "type": "text", "title": "Content" }
74
- ],
75
- "title": "Text",
76
- "entity": "text__c"
340
+ "title": "Módulo 2 - Fechamento",
341
+ "parent": "<trilha_id>",
342
+ "position": 1,
343
+ "unlock_policy": { "type": "progress", "folder_ref": "prev", "min_percent": 80 }
77
344
  }
78
345
  ```
79
346
 
80
- ## Casos de Uso Comuns
347
+ ### 4. Definir tipo de conteúdo
348
+ ```json
349
+ funifier_save type=folder-content-type
350
+ { "_id": "video", "entity": "video__c", "input": "repository", "title": "Vídeo" }
351
+ ```
81
352
 
82
- - **Curso Online:** Pasta raiz "Curso de Vendas" → Subpastas "Módulo 1", "Módulo 2" → Conteúdos (textos, vídeos, quizzes)
83
- - **Trilha de Capacitação:** Pastas representam etapas; cada etapa contém materiais e avaliações
84
- - **Catálogo de Produtos:** Pastas como categorias; conteúdos como fichas de produto
85
- - **Onboarding:** Pastas representam fases do onboarding; progresso monitora completude
353
+ ### 5. Adicionar conteúdo ao módulo
354
+ ```json
355
+ funifier_save type=folder-content
356
+ { "type": "video", "content": "<video_id>", "parent": "<modulo1_id>" }
357
+ ```
86
358
 
87
- ## Progresso do Jogador
359
+ ### 6. Registrar progresso do jogador
360
+ ```json
361
+ funifier_save type=folder-log
362
+ { "item": "<content_id>", "player": "player123", "status": "done" }
363
+ ```
88
364
 
89
- O Folder monitora automaticamente o progresso do jogador dentro da árvore de diretórios. Isso permite:
365
+ ### 7. Consultar progresso completo
366
+ ```json
367
+ funifier_folder operation=progress
368
+ { "folder": "<trilha_id>", "player": "player123" }
369
+ ```
90
370
 
91
- - Saber que um jogador completou X% de um curso
92
- - Registrar action logs ao progredir (aciona técnicas de jogos)
93
- - Criar desafios vinculados à completude de um folder (ex: "Complete o curso para ganhar 500 XP")
371
+ ---
94
372
 
95
373
  ## Integração com Outras Técnicas
96
374
 
97
375
  | Técnica | Integração |
98
376
  |---------|-----------|
99
- | **Challenge** | Desafio completado quando jogador termina todos os itens de um folder |
100
- | **Quiz** | Quizzes podem ser conteúdos dentro de um folder |
101
- | **Point** | Pontos concedidos ao progredir no folder |
102
- | **Achievement** | Conquista desbloqueada ao completar 100% do folder |
103
-
104
- ## Validações e Testes
105
-
106
- - [ ] Pasta aparece na lista
107
- - [ ] Hierarquia pai-filho funciona
108
- - [ ] Breadcrumb retorna caminho correto
109
- - [ ] Conteúdos são associados corretamente
110
- - [ ] Progresso do jogador é calculado corretamente
111
- - [ ] Action log é gerado ao progredir
377
+ | **Challenge** | Criar desafio vinculado à completion do folder (rule: `folder_progress` com `percent >= 100`) |
378
+ | **Point** | Conceder pontos via trigger `folder_progress` quando `current_percent >= 100` |
379
+ | **Achievement** | Conquista ao completar 100% de um folder |
380
+ | **Quiz** | Quiz como `FolderContent` dentro de um folder (via `folder-content-type` com `input=repository`) |
381
+
382
+ ## Checklist de Configuração
383
+
384
+ - [ ] Criar estrutura de pastas (raiz + sub-pastas com position)
385
+ - [ ] Definir FolderContentTypes necessários
386
+ - [ ] Adicionar FolderContent às pastas
387
+ - [ ] Configurar unlock_policy nas pastas que precisam de desbloqueio condicional
388
+ - [ ] Verificar árvore com `funifier_folder operation=inside`
389
+ - [ ] Testar progresso com `funifier_folder operation=progress`
390
+ - [ ] Configurar triggers em `folder_log` ou `folder_progress` se necessário
@@ -1,5 +1,5 @@
1
1
  import { FunifierConfig } from "./config";
2
- import { Trigger, Scheduler, Aggregate, Widget, CustomPage, PublicEndpoint, ChallengeAggregate, AiKnowledge, AuthModule, Websocket, Action, Challenge, Point, Level, LevelConfig, Leaderboard, LeaderboardEntry, Quiz, Question, VirtualGoodCatalog, VirtualGoodItem } from "./types";
2
+ import { Trigger, Scheduler, Aggregate, Widget, CustomPage, PublicEndpoint, ChallengeAggregate, AiKnowledge, AuthModule, Websocket, Action, Challenge, Point, Level, LevelConfig, Leaderboard, LeaderboardEntry, Quiz, Question, VirtualGoodCatalog, VirtualGoodItem, Folder, FolderContent, FolderContentType, FolderLog } from "./types";
3
3
  export declare function serializeToFunifierQuery(filter: Record<string, any>): string;
4
4
  export declare function createAPIClient(config: FunifierConfig): {
5
5
  listTriggers: () => Promise<Trigger[]>;
@@ -63,6 +63,20 @@ export declare function createAPIClient(config: FunifierConfig): {
63
63
  _id: string;
64
64
  title: string;
65
65
  }[]>;
66
+ listFolders: () => Promise<Folder[]>;
67
+ saveFolder: (payload: Folder) => Promise<Folder>;
68
+ deleteFolder: (id: string) => Promise<any>;
69
+ listFolderContents: () => Promise<FolderContent[]>;
70
+ saveFolderContent: (payload: FolderContent) => Promise<FolderContent>;
71
+ deleteFolderContent: (id: string) => Promise<any>;
72
+ listFolderContentTypes: () => Promise<FolderContentType[]>;
73
+ saveFolderContentType: (payload: FolderContentType) => Promise<FolderContentType>;
74
+ listFolderLogs: () => Promise<FolderLog[]>;
75
+ saveFolderLog: (payload: FolderLog) => Promise<FolderLog>;
76
+ deleteFolderLog: (id: string) => Promise<any>;
77
+ folderInside: (folderId: string) => Promise<any>;
78
+ folderProgress: (folderId: string, playerId: string) => Promise<any>;
79
+ folderBreadcrumb: (folderId: string) => Promise<any>;
66
80
  evaluateCron: (expression: string) => Promise<{
67
81
  valid: boolean;
68
82
  expression: string;
@@ -106,6 +120,12 @@ export declare function createAPIClient(config: FunifierConfig): {
106
120
  saveVirtualGoodCatalog: (payload: VirtualGoodCatalog) => Promise<VirtualGoodCatalog>;
107
121
  listVirtualGoodItems: () => Promise<VirtualGoodItem[]>;
108
122
  saveVirtualGoodItem: (payload: VirtualGoodItem) => Promise<VirtualGoodItem>;
123
+ deleteVirtualGoodCatalog: (id: string) => Promise<{
124
+ success: boolean;
125
+ }>;
126
+ deleteVirtualGoodItem: (id: string) => Promise<{
127
+ success: boolean;
128
+ }>;
109
129
  getGamification: (apiKey: string) => Promise<{
110
130
  _id: string;
111
131
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/core/api-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/core/api-client.ts"],"names":[],"mappings":"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"}