funifier-mcp 0.2.25 → 0.2.27

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 (211) hide show
  1. package/.cursor/rules/funifier.mdc +38 -41
  2. package/.github/copilot-instructions.md +38 -41
  3. package/AGENTS.md +56 -49
  4. package/README.md +40 -22
  5. package/datasource-funifier-docs/.coverage.json +326 -0
  6. package/datasource-funifier-docs/.validation.json +593 -0
  7. package/datasource-funifier-docs/knowledge/guides/aggregates.md +182 -70
  8. package/datasource-funifier-docs/knowledge/guides/database-access.md +174 -88
  9. package/datasource-funifier-docs/knowledge/guides/java-entities.md +294 -204
  10. package/datasource-funifier-docs/knowledge/guides/java-libraries.md +202 -226
  11. package/datasource-funifier-docs/knowledge/guides/java-managers.md +343 -265
  12. package/datasource-funifier-docs/knowledge/guides/trigger-examples.md +180 -236
  13. package/datasource-funifier-docs/knowledge/guides/triggers-guide.md +273 -191
  14. package/datasource-funifier-docs/knowledge/index.md +5 -2
  15. package/datasource-funifier-docs/knowledge/modules/achievement.md +1126 -28
  16. package/datasource-funifier-docs/knowledge/modules/action-log.md +469 -62
  17. package/datasource-funifier-docs/knowledge/modules/action.md +522 -70
  18. package/datasource-funifier-docs/knowledge/modules/auth.md +718 -69
  19. package/datasource-funifier-docs/knowledge/modules/avatar.md +483 -18
  20. package/datasource-funifier-docs/knowledge/modules/backup.md +603 -25
  21. package/datasource-funifier-docs/knowledge/modules/challenge.md +1048 -220
  22. package/datasource-funifier-docs/knowledge/modules/compact.md +469 -26
  23. package/datasource-funifier-docs/knowledge/modules/competition.md +811 -109
  24. package/datasource-funifier-docs/knowledge/modules/crossword.md +504 -28
  25. package/datasource-funifier-docs/knowledge/modules/csv-data.md +645 -20
  26. package/datasource-funifier-docs/knowledge/modules/custom-object.md +701 -36
  27. package/datasource-funifier-docs/knowledge/modules/database.md +730 -164
  28. package/datasource-funifier-docs/knowledge/modules/folder.md +1011 -77
  29. package/datasource-funifier-docs/knowledge/modules/kpi-formulas.md +410 -15
  30. package/datasource-funifier-docs/knowledge/modules/lastmile.md +568 -29
  31. package/datasource-funifier-docs/knowledge/modules/leaderboard.md +595 -126
  32. package/datasource-funifier-docs/knowledge/modules/level.md +536 -54
  33. package/datasource-funifier-docs/knowledge/modules/lottery.md +809 -76
  34. package/datasource-funifier-docs/knowledge/modules/marketplace.md +688 -17
  35. package/datasource-funifier-docs/knowledge/modules/mystery.md +662 -52
  36. package/datasource-funifier-docs/knowledge/modules/notification.md +564 -26
  37. package/datasource-funifier-docs/knowledge/modules/patterns.md +519 -814
  38. package/datasource-funifier-docs/knowledge/modules/player.md +773 -73
  39. package/datasource-funifier-docs/knowledge/modules/point.md +380 -83
  40. package/datasource-funifier-docs/knowledge/modules/public.md +508 -178
  41. package/datasource-funifier-docs/knowledge/modules/question.md +619 -99
  42. package/datasource-funifier-docs/knowledge/modules/quiz.md +565 -120
  43. package/datasource-funifier-docs/knowledge/modules/scheduler.md +1092 -39
  44. package/datasource-funifier-docs/knowledge/modules/security.md +674 -112
  45. package/datasource-funifier-docs/knowledge/modules/staging.md +742 -19
  46. package/datasource-funifier-docs/knowledge/modules/story.md +565 -29
  47. package/datasource-funifier-docs/knowledge/modules/studio-page.md +470 -144
  48. package/datasource-funifier-docs/knowledge/modules/swap.md +552 -84
  49. package/datasource-funifier-docs/knowledge/modules/team.md +563 -45
  50. package/datasource-funifier-docs/knowledge/modules/trigger.md +876 -134
  51. package/datasource-funifier-docs/knowledge/modules/upload.md +468 -95
  52. package/datasource-funifier-docs/knowledge/modules/virtual-good.md +510 -63
  53. package/datasource-funifier-docs/knowledge/modules/webhook.md +375 -28
  54. package/datasource-funifier-docs/knowledge/modules/websocket.md +459 -26
  55. package/datasource-funifier-docs/knowledge/modules/widget.md +613 -27
  56. package/dist/cli/init.d.ts.map +1 -1
  57. package/dist/cli/init.js +42 -1
  58. package/dist/cli/init.js.map +1 -1
  59. package/dist/cli/init.test.js +74 -3
  60. package/dist/cli/init.test.js.map +1 -1
  61. package/dist/cli/persona.d.ts +3 -0
  62. package/dist/cli/persona.d.ts.map +1 -0
  63. package/dist/cli/persona.js +25 -0
  64. package/dist/cli/persona.js.map +1 -0
  65. package/dist/core/api-client.d.ts +21 -1
  66. package/dist/core/api-client.d.ts.map +1 -1
  67. package/dist/core/api-client.js +154 -1
  68. package/dist/core/api-client.js.map +1 -1
  69. package/dist/core/constants.d.ts +14 -0
  70. package/dist/core/constants.d.ts.map +1 -1
  71. package/dist/core/constants.js +14 -0
  72. package/dist/core/constants.js.map +1 -1
  73. package/dist/core/types/Folder.d.ts +16 -0
  74. package/dist/core/types/Folder.d.ts.map +1 -0
  75. package/dist/core/types/Folder.js +3 -0
  76. package/dist/core/types/Folder.js.map +1 -0
  77. package/dist/core/types/FolderContent.d.ts +10 -0
  78. package/dist/core/types/FolderContent.d.ts.map +1 -0
  79. package/dist/core/types/FolderContent.js +3 -0
  80. package/dist/core/types/FolderContent.js.map +1 -0
  81. package/dist/core/types/FolderContentType.d.ts +10 -0
  82. package/dist/core/types/FolderContentType.d.ts.map +1 -0
  83. package/dist/core/types/FolderContentType.js +3 -0
  84. package/dist/core/types/FolderContentType.js.map +1 -0
  85. package/dist/core/types/FolderLog.d.ts +11 -0
  86. package/dist/core/types/FolderLog.d.ts.map +1 -0
  87. package/dist/core/types/FolderLog.js +3 -0
  88. package/dist/core/types/FolderLog.js.map +1 -0
  89. package/dist/core/types/index.d.ts +4 -0
  90. package/dist/core/types/index.d.ts.map +1 -1
  91. package/dist/core/types/index.js +4 -0
  92. package/dist/core/types/index.js.map +1 -1
  93. package/dist/mcp/bundle.js +121 -87
  94. package/dist/mcp/check-update.d.ts +2 -0
  95. package/dist/mcp/check-update.d.ts.map +1 -0
  96. package/dist/mcp/check-update.js +44 -0
  97. package/dist/mcp/check-update.js.map +1 -0
  98. package/dist/mcp/index.js +5 -2
  99. package/dist/mcp/index.js.map +1 -1
  100. package/dist/mcp/resources/documentation.d.ts +1 -1
  101. package/dist/mcp/resources/documentation.d.ts.map +1 -1
  102. package/dist/mcp/resources/documentation.js +39 -3
  103. package/dist/mcp/resources/documentation.js.map +1 -1
  104. package/dist/mcp/tools/_char-guard.js +1 -1
  105. package/dist/mcp/tools/_char-guard.js.map +1 -1
  106. package/dist/mcp/tools/_fetch-current.d.ts +1 -1
  107. package/dist/mcp/tools/_fetch-current.d.ts.map +1 -1
  108. package/dist/mcp/tools/_fetch-current.js +12 -0
  109. package/dist/mcp/tools/_fetch-current.js.map +1 -1
  110. package/dist/mcp/tools/connect.d.ts.map +1 -1
  111. package/dist/mcp/tools/connect.js +18 -8
  112. package/dist/mcp/tools/connect.js.map +1 -1
  113. package/dist/mcp/tools/database.d.ts.map +1 -1
  114. package/dist/mcp/tools/database.js +59 -47
  115. package/dist/mcp/tools/database.js.map +1 -1
  116. package/dist/mcp/tools/database.test.js +2 -2
  117. package/dist/mcp/tools/database.test.js.map +1 -1
  118. package/dist/mcp/tools/delete.d.ts.map +1 -1
  119. package/dist/mcp/tools/delete.js +33 -3
  120. package/dist/mcp/tools/delete.js.map +1 -1
  121. package/dist/mcp/tools/execute.d.ts.map +1 -1
  122. package/dist/mcp/tools/execute.js +20 -9
  123. package/dist/mcp/tools/execute.js.map +1 -1
  124. package/dist/mcp/tools/folder.d.ts +4 -0
  125. package/dist/mcp/tools/folder.d.ts.map +1 -0
  126. package/dist/mcp/tools/folder.js +68 -0
  127. package/dist/mcp/tools/folder.js.map +1 -0
  128. package/dist/mcp/tools/get.d.ts.map +1 -1
  129. package/dist/mcp/tools/get.js +16 -6
  130. package/dist/mcp/tools/get.js.map +1 -1
  131. package/dist/mcp/tools/index.d.ts +1 -1
  132. package/dist/mcp/tools/index.d.ts.map +1 -1
  133. package/dist/mcp/tools/index.js +5 -1
  134. package/dist/mcp/tools/index.js.map +1 -1
  135. package/dist/mcp/tools/list.d.ts.map +1 -1
  136. package/dist/mcp/tools/list.js +38 -14
  137. package/dist/mcp/tools/list.js.map +1 -1
  138. package/dist/mcp/tools/logs.d.ts.map +1 -1
  139. package/dist/mcp/tools/logs.js +15 -5
  140. package/dist/mcp/tools/logs.js.map +1 -1
  141. package/dist/mcp/tools/save.d.ts.map +1 -1
  142. package/dist/mcp/tools/save.js +26 -4
  143. package/dist/mcp/tools/save.js.map +1 -1
  144. package/dist/mcp/tools/save.test.js +192 -1
  145. package/dist/mcp/tools/save.test.js.map +1 -1
  146. package/dist/mcp/tools/search-docs.d.ts +3 -0
  147. package/dist/mcp/tools/search-docs.d.ts.map +1 -0
  148. package/dist/mcp/tools/search-docs.js +102 -0
  149. package/dist/mcp/tools/search-docs.js.map +1 -0
  150. package/package.json +6 -2
  151. package/skills/acquire-funifier-knowledge/SKILL.md +132 -0
  152. package/skills/acquire-funifier-knowledge/assets/templates/CONCERNS.md +25 -0
  153. package/skills/acquire-funifier-knowledge/assets/templates/CUSTOM_ENDPOINTS.md +24 -0
  154. package/skills/acquire-funifier-knowledge/assets/templates/CUSTOM_PAGES.md +24 -0
  155. package/skills/acquire-funifier-knowledge/assets/templates/GAME_MECHANICS.md +35 -0
  156. package/skills/acquire-funifier-knowledge/assets/templates/INTEGRATIONS.md +35 -0
  157. package/skills/acquire-funifier-knowledge/assets/templates/LEADERBOARDS.md +24 -0
  158. package/skills/acquire-funifier-knowledge/assets/templates/OVERVIEW.md +47 -0
  159. package/skills/acquire-funifier-knowledge/assets/templates/PLAYER_MODEL.md +31 -0
  160. package/skills/acquire-funifier-knowledge/assets/templates/SCHEDULERS.md +25 -0
  161. package/skills/acquire-funifier-knowledge/assets/templates/TECHNIQUES_AND_PATTERNS.md +26 -0
  162. package/skills/acquire-funifier-knowledge/assets/templates/TRIGGERS.md +27 -0
  163. package/skills/acquire-funifier-knowledge/references/funifier-inventory-checklist.md +81 -0
  164. package/skills/acquire-funifier-knowledge/references/game-techniques-taxonomy.md +62 -0
  165. package/skills/acquire-funifier-knowledge/references/mcp-call-patterns.md +118 -0
  166. package/skills/funifier/SKILL.md +88 -0
  167. package/skills/funifier/references/configure-security.md +96 -0
  168. package/skills/{funifier-create-action/SKILL.md → funifier/references/create-action.md} +0 -33
  169. package/skills/funifier/references/create-aggregate.md +144 -0
  170. package/skills/funifier/references/create-challenge.md +116 -0
  171. package/skills/funifier/references/create-competition.md +98 -0
  172. package/skills/funifier/references/create-crossword.md +574 -0
  173. package/skills/funifier/references/create-custom-object.md +91 -0
  174. package/skills/funifier/references/create-custom-page.md +135 -0
  175. package/skills/funifier/references/create-folder.md +104 -0
  176. package/skills/funifier/references/create-lastmile.md +643 -0
  177. package/skills/{funifier-create-leaderboard/SKILL.md → funifier/references/create-leaderboard.md} +0 -33
  178. package/skills/funifier/references/create-level.md +94 -0
  179. package/skills/funifier/references/create-lottery.md +913 -0
  180. package/skills/funifier/references/create-mystery.md +769 -0
  181. package/skills/funifier/references/create-notification.md +75 -0
  182. package/skills/{funifier-create-point/SKILL.md → funifier/references/create-point.md} +0 -33
  183. package/skills/funifier/references/create-quiz.md +98 -0
  184. package/skills/funifier/references/create-scheduler.md +141 -0
  185. package/skills/funifier/references/create-story.md +636 -0
  186. package/skills/funifier/references/create-swap.md +95 -0
  187. package/skills/{funifier-create-trigger/SKILL.md → funifier/references/create-trigger.md} +0 -33
  188. package/skills/funifier/references/create-virtual-good.md +96 -0
  189. package/skills/funifier/references/create-webhook.md +72 -0
  190. package/skills/funifier/references/create-websocket.md +71 -0
  191. package/skills/funifier/references/create-widget.md +76 -0
  192. package/skills/funifier/references/debug.md +87 -0
  193. package/skills/funifier/references/help.md +81 -0
  194. package/skills/funifier/references/implement-frontend.md +106 -0
  195. package/skills/funifier/references/import-csv.md +75 -0
  196. package/skills/funifier/references/manage-player.md +82 -0
  197. package/skills/funifier/references/manage-team.md +76 -0
  198. package/skills/funifier/references/upload-file.md +91 -0
  199. package/datasource-funifier-docs/.search-index.json +0 -17318
  200. package/datasource-funifier-docs/.skills-map.json +0 -73
  201. package/skills/funifier-create-aggregate/SKILL.md +0 -127
  202. package/skills/funifier-create-challenge/SKILL.md +0 -88
  203. package/skills/funifier-create-custom-page/SKILL.md +0 -127
  204. package/skills/funifier-create-level/SKILL.md +0 -87
  205. package/skills/funifier-create-quiz/SKILL.md +0 -87
  206. package/skills/funifier-create-scheduler/SKILL.md +0 -127
  207. package/skills/funifier-create-virtual-good/SKILL.md +0 -87
  208. package/skills/funifier-debug/SKILL.md +0 -92
  209. package/skills/funifier-help/SKILL.md +0 -86
  210. package/skills/funifier-implement-frontend/SKILL.md +0 -90
  211. package/skills/funifier-index/SKILL.md +0 -58
@@ -1,330 +1,306 @@
1
1
  # Java Libraries — Referência
2
2
 
3
- Bibliotecas e utilitários disponíveis para uso em **triggers**, **schedulers** e **public endpoints**.
3
+ ## 1. Visão Geral
4
4
 
5
- ---
5
+ ### 1.1 O que é este documento
6
6
 
7
- ## JsonUtil
7
+ Este documento descreve as bibliotecas e utilitários disponíveis no runtime Java/Groovy da Funifier (triggers, schedulers e public endpoints) — assinatura, uso e em quais runtimes cada um funciona.
8
8
 
9
- **Classe:** `com.funifier.engine.util.JsonUtil`
9
+ ### 1.2 Quando consultar
10
10
 
11
- Utilitário estático para serialização/deserialização JSON (baseado em Jackson).
11
+ - Consulte ao precisar **serializar/desserializar JSON** (`JsonUtil`).
12
+ - Consulte ao precisar **gerar IDs ou códigos** (`Guid`).
13
+ - Consulte ao precisar **calcular datas em código** (`DateUtil`).
14
+ - Consulte ao precisar fazer **requisição HTTP** a partir de código server-side (`Unirest`).
15
+ - Consulte ao precisar **enviar email** via SMTP (`EmailBuilder`).
16
+ - Consulte ao decidir **se uma classe funciona no Public Endpoint** (sandbox).
12
17
 
13
- | Método | Retorno | Descrição |
14
- |--------|---------|-----------|
15
- | `toJson(Object obj)` | String | Converte objeto para JSON string |
16
- | `toJsonRemoveNullFields(Object obj)` | String | Converte para JSON excluindo campos null |
17
- | `fromJson(String json, Class<T> valueType)` | T | Converte JSON string para objeto tipado |
18
- | `fromJsonToMap(String json)` | Map\<String, Object\> | Converte JSON string para Map |
19
- | `toBsonStrictMode(Object obj)` | String | Converte para BSON strict mode (MongoDB) |
18
+ ### 1.3 Quando NÃO consultar
20
19
 
21
- **Exemplos:**
20
+ - **NÃO** consulte para **acesso ao banco** (Jongo, find/save/aggregate) — use `datasource-funifier-docs/knowledge/guides/database-access.md`. Este documento só aponta para lá.
21
+ - **NÃO** consulte para a **semântica das expressões de data** (`-0M-`, `-1d+`) — use `datasource-funifier-docs/knowledge/guides/aggregates.md`. Aqui ficam apenas os métodos Java de `DateUtil`.
22
+ - **NÃO** consulte para **managers/entidades** — use `java-managers.md` e `java-entities.md`.
22
23
 
23
- ```java
24
- // Objeto para JSON
25
- HashMap data = new HashMap();
26
- data.put("name", "John");
27
- data.put("score", 100);
28
- String json = JsonUtil.toJson(data);
29
- // {"name":"John","score":100}
24
+ ### 1.4 Índice de decisão
30
25
 
31
- // JSON para Map
32
- Map<String, Object> map = JsonUtil.fromJsonToMap("{\"name\":\"John\",\"score\":100}");
33
- String name = (String) map.get("name");
26
+ | Problema / Situação | O que usar | Seção |
27
+ |---|---|---|
28
+ | Converter objeto JSON | `JsonUtil` | §2 |
29
+ | Gerar ID único ou código curto | `Guid` | §3 |
30
+ | Calcular/parsear/formatar data em código | `DateUtil` | §4 |
31
+ | Fazer requisição HTTP externa | `Unirest` (ou `java.net.URL` no Public Endpoint) | §5 |
32
+ | Enviar email SMTP | `EmailBuilder` / `MailerBuilder` | §6 |
33
+ | Hashear senha de jogador | `BCrypt` | §7 |
34
+ | Acessar MongoDB | (ver `database-access.md`) | §8 |
34
35
 
35
- // JSON para objeto tipado
36
- Player player = JsonUtil.fromJson(jsonString, Player.class);
36
+ ### 1.5 Restrições globais críticas
37
37
 
38
- // Ignorar campos null
39
- String cleanJson = JsonUtil.toJsonRemoveNullFields(obj);
40
- ```
38
+ > ⚠️ **O sandbox do Public Endpoint bloqueia bibliotecas que funcionam em Trigger/Scheduler.** Consequência: código portado de uma trigger lança `MissingPropertyException`/`ClassCastException` no Public Endpoint. → Antes de usar uma biblioteca num Public Endpoint, confira a coluna **Disponível em** de cada seção e a tabela completa do sandbox em `patterns.md` §1.5. Resumo: `Unirest` (`com.mashape.*`), `EmailBuilder` (`org.simplejavamail`), `BCrypt` e qualquer nome `com.*`/`org.*` totalmente qualificado são **bloqueados** no Public Endpoint; `JsonUtil`/`DateUtil` (nome curto) funcionam.
39
+
40
+ ### 1.6 Documentos relacionados
41
+
42
+ > 📄 `datasource-funifier-docs/knowledge/guides/database-access.md` — Jongo e operações de banco
43
+ > 📄 `datasource-funifier-docs/knowledge/guides/aggregates.md` — semântica das expressões de data Funifier
44
+ > 📄 `datasource-funifier-docs/knowledge/modules/public.md` — runtime e sandbox de Public Endpoints
41
45
 
42
46
  ---
43
47
 
44
- ## Guid
48
+ ## 2. JsonUtil
49
+
50
+ Quando usar: serializar objetos para JSON ou parsear JSON em código.
51
+ Não usar quando: precisar de `JsonSlurper`/`JsonOutput` no Public Endpoint — são bloqueados (`patterns.md` §1.5); use `JsonUtil`.
52
+ Depende de: —
53
+ Disponível em: Todos (uso em Public Endpoint confirmado em `patterns.md` §6).
54
+
55
+ ### Descrição
45
56
 
46
- **Classe:** `com.funifier.engine.guid.Guid`
57
+ Utilitário estático para serialização/desserialização JSON (baseado em Jackson). Classe `com.funifier.engine.util.JsonUtil`. Por ser pré-importado com nome curto, funciona no sandbox do Public Endpoint (ao contrário de `groovy.json.*`).
47
58
 
48
- Geração de identificadores únicos.
59
+ ### Uso
49
60
 
50
61
  | Método | Retorno | Descrição |
51
62
  |--------|---------|-----------|
52
- | `newShortGuid()` | String | Gera ID único (MongoDB ObjectId, 24 chars) |
53
- | `shortTimeMillis()` | String | Gera código baseado no timestamp (base62, ~7 chars) |
54
-
55
- **Exemplos:**
63
+ | `toJson(Object obj)` | String | Objeto JSON |
64
+ | `toJsonRemoveNullFields(Object obj)` | String | Objeto JSON sem campos null |
65
+ | `fromJson(String json, Class<T> valueType)` | T | JSON → objeto tipado |
66
+ | `fromJsonToMap(String json)` | Map\<String, Object\> | JSON → Map |
67
+ | `toBsonStrictMode(Object obj)` | String | Objeto → BSON strict mode (MongoDB) |
56
68
 
57
69
  ```java
58
- // Gerar ID para novo objeto
59
- String id = Guid.newShortGuid();
60
- // Ex: "64a5d92f1b2c3d4e5f6a7b8c"
70
+ HashMap data = new HashMap();
71
+ data.put("name", "John");
72
+ String json = JsonUtil.toJson(data); // {"name":"John"}
61
73
 
62
- // Gerar código curto baseado no tempo (útil para códigos de convite)
63
- String code = Guid.shortTimeMillis();
64
- // Ex: "y6z3D6H"
74
+ Map<String, Object> map = JsonUtil.fromJsonToMap(json);
75
+ Player player = JsonUtil.fromJson(jsonString, Player.class);
65
76
  ```
66
77
 
67
- **Quando usar cada um:**
68
- - `newShortGuid()` Para IDs de objetos (achievements, action logs, etc.)
69
- - `shortTimeMillis()` Para códigos legíveis (convites, vouchers, etc.)
78
+ ```groovy
79
+ // No Public Endpoint: parsear o payload SEM JsonSlurper (ver patterns.md §1.5)
80
+ def body = JsonUtil.fromJsonToMap(JsonUtil.toJson(payload))
81
+ ```
70
82
 
71
- ---
83
+ ### Armadilhas conhecidas
72
84
 
73
- ## DateUtil
85
+ - **`JsonSlurper`/`JsonOutput` no Public Endpoint** → `ClassCastException: [B incompatible with [C`. Causa: bloqueio do sandbox. Correção: `JsonUtil.fromJsonToMap()` (`patterns.md` §6).
74
86
 
75
- **Classe:** `com.funifier.engine.util.DateUtil`
87
+ ---
76
88
 
77
- Utilitário para cálculos e parsing de datas, incluindo as **expressões de data Funifier**.
89
+ ## 3. Guid
78
90
 
79
- ### Expressões de Data (Funifier Syntax)
91
+ Quando usar: gerar IDs de objetos novos ou códigos curtos legíveis.
92
+ Não usar quando: o objeto já tem `_id` definido pela API (ex: documento vindo de `findOne`).
93
+ Depende de: —
94
+ Disponível em: Trigger / Scheduler (uso em Public Endpoint não verificado nas fontes).
80
95
 
81
- Formato: `[sinal][quantidade][unidade][ajuste]`
96
+ ### Descrição
82
97
 
83
- **Unidades:** `y`=ano, `M`=mês, `w`=semana, `d`=dia, `h`=hora, `m`=minuto, `s`=segundo
98
+ Geração de identificadores únicos. Classe `com.funifier.engine.guid.Guid`.
84
99
 
85
- **Ajuste:** `-` = início da unidade (floor), `+` = fim da unidade (ceil), sem ajuste = exato
100
+ ### Uso
86
101
 
87
- | Expressão | Significado |
88
- |-----------|------------|
89
- | `-0d` | Agora |
90
- | `-0d-` | Início do dia atual (00:00:00) |
91
- | `-0d+` | Fim do dia atual (23:59:59) |
92
- | `-1d` | Exatamente 1 dia atrás |
93
- | `-1d-` | Início do dia anterior |
94
- | `-1d+` | Fim do dia anterior |
95
- | `+1d` | Exatamente 1 dia no futuro |
96
- | `+1d-` | Início do dia seguinte |
97
- | `-0w-` | Início da semana atual |
98
- | `-0w+` | Fim da semana atual |
99
- | `-0M-` | Primeiro dia do mês (00:00:00) |
100
- | `-0M+` | Último dia do mês (23:59:59) |
101
- | `-1M-` | Primeiro dia do mês anterior |
102
- | `-0y-` | 1 de janeiro do ano atual |
103
- | `-0y+` | 31 de dezembro do ano atual |
102
+ | Método | Retorno | Quando usar |
103
+ |--------|---------|-------------|
104
+ | `newShortGuid()` | String | IDs de objetos (achievements, action logs) — MongoDB ObjectId, 24 chars |
105
+ | `shortTimeMillis()` | String | Códigos legíveis (convites, vouchers) — base62, ~7 chars |
104
106
 
105
- **Encadeamento com `|`:**
106
- ```
107
- -1d+|GMT+3 → fim do dia anterior no fuso GMT+3
108
- -0d-|+5h|+30m|GMT-3 → início do dia + 5h30m no fuso GMT-3
107
+ ```java
108
+ String id = Guid.newShortGuid(); // "64a5d92f1b2c3d4e5f6a7b8c"
109
+ String code = Guid.shortTimeMillis(); // "y6z3D6H"
109
110
  ```
110
111
 
111
- ### Métodos
112
+ ### Armadilhas conhecidas
113
+
114
+ - **Atribuir o ID gerado a `entity._id` em Groovy** → não persiste. Use `entity.id` (`java-entities.md` §1.5).
115
+
116
+ ---
117
+
118
+ ## 4. DateUtil
119
+
120
+ Quando usar: calcular, parsear ou formatar datas em código Java/Groovy.
121
+ Não usar quando: precisar das expressões de data dentro de **queries/aggregates** (`{"$date": "-0M-"}`) — a semântica completa está em `aggregates.md`.
122
+ Depende de: expressões de data Funifier (definidas em `aggregates.md`).
123
+ Disponível em: Todos (uso em Public Endpoint confirmado em `patterns.md` §6 — `DateUtil.fromKeyword("+7d")`).
124
+
125
+ ### Descrição
126
+
127
+ Utilitário para cálculo, parsing e formatação de datas, incluindo a conversão das **expressões de data Funifier** em `Date`. Classe `com.funifier.engine.util.DateUtil`.
128
+
129
+ > A tabela de expressões (`-0d`, `-0M-`, `-1d+`, encadeamento com `|GMT±N`) é mantida em `datasource-funifier-docs/knowledge/guides/aggregates.md` (dono único). Aqui ficam apenas os **métodos Java**.
130
+
131
+ ### Uso
112
132
 
113
133
  | Método | Retorno | Descrição |
114
134
  |--------|---------|-----------|
115
- | `fromKeyword(String keyword)` | Date | Converte expressão Funifier em Date |
116
- | `fromKeyword(String keyword, Date reference)` | Date | Converte com data de referência |
117
- | `fromKeyword(String keyword, Date reference, String timezone)` | Date | Converte com referência e timezone |
118
- | `fromKeywordPeriodExpression(String period)` | Date[] | Converte período (ex: "-0M-;-0M+") em [inicio, fim] |
135
+ | `fromKeyword(String keyword)` | Date | Expressão Funifier Date |
136
+ | `fromKeyword(String keyword, Date reference)` | Date | Com data de referência |
137
+ | `fromKeyword(String keyword, Date reference, String timezone)` | Date | Com referência e timezone |
138
+ | `fromKeywordPeriodExpression(String period)` | Date[] | Período `"-0M-;-0M+"` `[início, fim]` |
119
139
  | `parse(Object date)` | Date | Parse genérico (Date, Long, String, expressão) |
120
- | `parse(String date, String pattern)` | Date | Parse com padrão SimpleDateFormat |
121
- | `format(Date date, String pattern)` | String | Formata data com padrão SimpleDateFormat |
122
- | `between(Date ref, int scale, int amount)` | Date[] | Intervalo [inicio, fim] da unidade |
123
- | `add(Date ref, int scale, int amount)` | Date | Adiciona unidades à data |
124
- | `reset(Date date, int scale)` | Date | Trunca data para o início da unidade |
140
+ | `parse(String date, String pattern)` | Date | Parse com `SimpleDateFormat` |
141
+ | `format(Date date, String pattern)` | String | Formata com `SimpleDateFormat` |
142
+ | `between(Date ref, int scale, int amount)` | Date[] | Intervalo `[início, fim]` da unidade |
143
+ | `add(Date ref, int scale, int amount)` | Date | Adiciona unidades |
144
+ | `reset(Date date, int scale)` | Date | Trunca para o início da unidade |
125
145
 
126
- **Escalas (TimeScale):**
127
- ```java
128
- TimeScale.MILLISECOND = 0;
129
- TimeScale.SECOND = 1;
130
- TimeScale.MINUTE = 2;
131
- TimeScale.HOUR = 3;
132
- TimeScale.DAY = 4;
133
- TimeScale.WEEK = 5;
134
- TimeScale.MONTH = 6;
135
- TimeScale.YEAR = 7;
136
- ```
137
-
138
- **Exemplos:**
146
+ **Escalas (`TimeScale`):** `MILLISECOND=0`, `SECOND=1`, `MINUTE=2`, `HOUR=3`, `DAY=4`, `WEEK=5`, `MONTH=6`, `YEAR=7`.
139
147
 
140
148
  ```java
141
- // Usar expressões Funifier
142
149
  Date inicioMes = DateUtil.fromKeyword("-0M-");
143
- Date fimMes = DateUtil.fromKeyword("-0M+");
144
- Date ontem = DateUtil.fromKeyword("-1d");
145
-
146
- // Período completo
147
150
  Date[] periodo = DateUtil.fromKeywordPeriodExpression("-0M-;-0M+");
148
- Date inicio = periodo[0];
149
- Date fim = periodo[1];
150
-
151
- // Parse genérico
152
- Date d1 = DateUtil.parse("2023-07-05T20:57:33.303Z");
153
- Date d2 = DateUtil.parse("-1d");
154
-
155
- // Formatar data
156
- String formatted = DateUtil.format(new Date(), "dd/MM/yyyy HH:mm:ss");
157
-
158
- // Adicionar tempo
159
151
  Date amanha = DateUtil.add(new Date(), TimeScale.DAY, 1);
160
- Date mesPassado = DateUtil.add(new Date(), TimeScale.MONTH, -1);
152
+ String fmt = DateUtil.format(new Date(), "dd/MM/yyyy HH:mm:ss");
161
153
  ```
162
154
 
163
- > **Referência completa de expressões de data em consultas:** consulte `guides/aggregates.md`.
155
+ ### Armadilhas conhecidas
156
+
157
+ - **Usar `System.currentTimeMillis()` no Public Endpoint** → bloqueado. Correção: `new Date().getTime()` (`patterns.md` §1.5).
164
158
 
165
159
  ---
166
160
 
167
- ## Unirest
161
+ ## 5. Unirest
162
+
163
+ Quando usar: requisição HTTP a API externa a partir de **trigger ou scheduler**.
164
+ Não usar quando: estiver num **Public Endpoint** — `com.mashape.*` é `com.*` → bloqueado; use `java.net.URL`/`openConnection()`.
165
+ Depende de: `JsonUtil` (para body JSON).
166
+ Disponível em: **Trigger / Scheduler** (bloqueado em Public Endpoint — `patterns.md` §1.5).
168
167
 
169
- **Biblioteca:** `com.mashape.unirest`
168
+ ### Descrição
170
169
 
171
- Cliente HTTP para fazer requisições a APIs externas.
170
+ Cliente HTTP. Biblioteca `com.mashape.unirest`.
172
171
 
173
- **Exemplos:**
172
+ ### Uso
174
173
 
175
174
  ```java
176
175
  // GET
177
- HttpResponse<String> response = Unirest.get("https://api.example.com/data")
176
+ HttpResponse<String> res = Unirest.get("https://api.example.com/data")
178
177
  .header("Authorization", "Bearer token123")
179
178
  .asString();
180
- String body = response.getBody();
181
- int status = response.getStatus();
179
+ String body = res.getBody();
180
+ int status = res.getStatus();
182
181
 
183
182
  // POST com JSON
184
- HashMap payload = new HashMap();
185
- payload.put("name", "John");
186
- payload.put("email", "john@email.com");
187
-
188
- HttpResponse<String> response = Unirest.post("https://api.example.com/users")
183
+ HttpResponse<String> res = Unirest.post("https://api.example.com/users")
189
184
  .header("Content-Type", "application/json")
190
185
  .body(JsonUtil.toJson(payload))
191
186
  .asString();
192
187
 
193
- // POST form
194
- HttpResponse<String> response = Unirest.post("https://api.example.com/form")
195
- .field("username", "john")
196
- .field("password", "secret")
197
- .asString();
188
+ // POST form / PUT / DELETE
189
+ Unirest.post(url).field("username", "john").field("password", "secret").asString();
190
+ Unirest.put(url).header("Content-Type", "application/json").body(JsonUtil.toJson(payload)).asString();
191
+ Unirest.delete(url).asString();
192
+ ```
198
193
 
199
- // PUT
200
- HttpResponse<String> response = Unirest.put("https://api.example.com/users/1")
201
- .header("Content-Type", "application/json")
202
- .body(JsonUtil.toJson(payload))
203
- .asString();
194
+ ### Armadilhas conhecidas
204
195
 
205
- // DELETE
206
- HttpResponse<String> response = Unirest.delete("https://api.example.com/users/1")
207
- .asString();
208
- ```
196
+ - **Unirest no Public Endpoint** → `MissingPropertyException` (é `com.*`). Correção: `java.net.URL`/`openConnection()` (`patterns.md` §6).
197
+ - **HTTP lento estourando o timeout** → Public Endpoint tem default 10s, Trigger 5s (`patterns.md` §1.5). Correção: chamadas rápidas ou aumentar `timeout` via API.
209
198
 
210
199
  ---
211
200
 
212
- ## EmailBuilder (SimpleJavaMail)
201
+ ## 6. EmailBuilder (SimpleJavaMail)
202
+
203
+ Quando usar: enviar email via SMTP a partir de **trigger ou scheduler**.
204
+ Não usar quando: estiver num Public Endpoint (`org.simplejavamail` é `org.*` → bloqueado); ou quando uma notificação in-app basta → `modules/notification.md`.
205
+ Depende de: servidor SMTP configurado na gamificação.
206
+ Disponível em: **Trigger / Scheduler** (bloqueado em Public Endpoint — `patterns.md` §3).
213
207
 
214
- **Biblioteca:** `org.simplejavamail`
208
+ ### Descrição
215
209
 
216
- Envio de emails via SMTP.
210
+ Construção e envio de emails. Biblioteca `org.simplejavamail`.
217
211
 
218
- **Exemplos:**
212
+ ### Uso
219
213
 
220
214
  ```java
221
- // Enviar email simples
222
- Email email = EmailBuilder
223
- .startingBlank()
215
+ Email email = EmailBuilder.startingBlank()
224
216
  .from("Company", "noreply@company.com")
225
217
  .to("John", "john@email.com")
226
218
  .withSubject("Welcome!")
227
- .withPlainText("Welcome to our platform!")
219
+ .withHTMLText("<h1>Hello</h1>") // ou .withPlainText("...")
228
220
  .buildEmail();
229
221
 
230
222
  MailerBuilder.withSMTPServer("smtp.host.com", 587, "login", "password")
231
223
  .buildMailer()
232
224
  .sendMail(email);
225
+ ```
233
226
 
234
- // Email com HTML
235
- Email email = EmailBuilder
236
- .startingBlank()
237
- .from("Company", "noreply@company.com")
238
- .to("John", "john@email.com")
239
- .withSubject("Report")
240
- .withHTMLText("<h1>Hello</h1><p>Your monthly report is ready.</p>")
241
- .buildEmail();
227
+ Para o padrão completo (template editável + SMTP da gamificação via `MailContext`), ver `patterns.md` §3.
242
228
 
243
- MailerBuilder.withSMTPServer("smtp.host.com", 587, "login", "password")
244
- .buildMailer()
245
- .sendMail(email);
229
+ ### Armadilhas conhecidas
230
+
231
+ - **Enviar email de um Public Endpoint** → bloqueado (`patterns.md` §3). Correção: envie de trigger/scheduler.
232
+
233
+ ---
234
+
235
+ ## 7. BCrypt
236
+
237
+ Quando usar: hashear senha de jogador server-side antes de `PlayerManager.insert`.
238
+ Não usar quando: estiver num Public Endpoint — `BCrypt` é indisponível no sandbox; delegue ao trigger `before_update` (`patterns.md` §4).
239
+ Depende de: —
240
+ Disponível em: **Trigger / Scheduler** (indisponível em Public Endpoint — `patterns.md` §1.5).
241
+
242
+ ### Descrição
243
+
244
+ Hash de senha. Classe `com.funifier.engine.util.BCrypt`. Necessário porque `POST/PUT /v3/player` grava `password` **sem hash** (`java-entities.md` §1.5; `patterns.md` §2).
245
+
246
+ ### Uso
247
+
248
+ ```groovy
249
+ p.password = com.funifier.engine.util.BCrypt.hashpw(
250
+ entity.password, com.funifier.engine.util.BCrypt.gensalt());
246
251
  ```
247
252
 
253
+ ### Armadilhas conhecidas
254
+
255
+ - **Tentar `BCrypt` no Public Endpoint** → indisponível. Correção: hashear via trigger `signup__c`/`change_password__c` (`patterns.md` §2, §11).
256
+
248
257
  ---
249
258
 
250
- ## Jongo (Acesso ao MongoDB)
259
+ ## 8. Jongo (Acesso ao MongoDB)
260
+
261
+ Quando usar: ler/escrever coleções diretamente em código.
262
+ Não usar quando: existir um manager para a operação → `java-managers.md`.
263
+ Depende de: `database` (param do trigger) ou `manager.getJongoConnection()`.
264
+ Disponível em: Todos (via `manager.getJongoConnection()`; uso em Public Endpoint confirmado em `patterns.md` §6).
251
265
 
252
- **Biblioteca:** `org.jongo`
266
+ ### Descrição
253
267
 
254
- Acesso direto ao MongoDB através do objeto `database` (em triggers) ou `manager.getJongoConnection()`.
268
+ Acesso direto ao MongoDB. Biblioteca `org.jongo`.
255
269
 
256
- ### Operações
270
+ > Operações completas (find, save, remove, count, aggregate, placeholders `#`) são documentadas em **`datasource-funifier-docs/knowledge/guides/database-access.md`** (dono único). Resumo abaixo apenas para orientar.
271
+
272
+ ### Uso
257
273
 
258
274
  ```java
259
- // Obter coleção
260
- org.jongo.MongoCollection collection = database.getCollection("nome_colecao");
261
-
262
- // --- INSERT / UPDATE ---
263
- // Save (insere ou atualiza se _id existir)
264
- database.getCollection("email__c").save(hashMap);
265
-
266
- // --- FIND ---
267
- // Buscar um documento
268
- Object result = database.getCollection("player")
269
- .findOne("{_id: 'john'}").as(Object.class);
270
-
271
- // Buscar com parâmetro (#)
272
- Object result = database.getCollection("product__c")
273
- .findOne("{_id: #}", productId).as(Object.class);
274
-
275
- // Buscar vários
276
- Iterable<Object> results = database.getCollection("action_log")
277
- .find("{userId: #}", "john").as(Object.class);
278
-
279
- // Buscar com projeção
280
- Object result = database.getCollection("player")
281
- .findOne("{_id: #}", id)
282
- .projection("{name: 1, email: 1}")
283
- .as(Object.class);
284
-
285
- // --- DELETE ---
286
- database.getCollection("car__c").remove("{_id: 'car001'}");
287
-
288
- // --- COUNT ---
289
- long total = database.getCollection("action_log")
290
- .count("{userId: #}", "john");
291
-
292
- // --- AGGREGATE ---
293
- Iterable<Object> result = database.getCollection("achievement")
294
- .aggregate("{$match: {type: 0, item: 'xp'}}")
295
- .and("{$group: {_id: '$player', total: {$sum: '$total'}}}")
296
- .and("{$sort: {total: -1}}")
297
- .and("{$limit: 10}")
298
- .as(Object.class);
275
+ // Em trigger: usar o param `database`. Em scheduler/endpoint: manager.getJongoConnection()
276
+ database.getCollection("player").findOne("{_id: #}", id).as(Map.class);
277
+ manager.getJongoConnection().getCollection("email__c").save(payload);
299
278
  ```
300
279
 
301
- ### Parâmetros com `#`
280
+ ### Armadilhas conhecidas
302
281
 
303
- O Jongo usa `#` como placeholder para parâmetros seguros (evita injection):
282
+ - **Concatenar valores na query string** injeção. Use o placeholder `#` (`database-access.md`).
304
283
 
305
- ```java
306
- // Um parâmetro
307
- database.getCollection("player").findOne("{_id: #}", playerId).as(Object.class);
284
+ ---
308
285
 
309
- // Múltiplos parâmetros
310
- database.getCollection("action_log")
311
- .find("{userId: #, actionId: #}", "john", "sell")
312
- .as(Object.class);
313
- ```
286
+ ## 9. Utilitários referenciados sem documentação completa
314
287
 
315
- > **Referência completa:** consulte `guides/database-access.md` e `guides/aggregates.md`.
288
+ > ⚠️ Documentação pendente: as classes abaixo são usadas em `patterns.md` mas não têm referência de API nas fontes atuais. Documentadas aqui apenas como ponteiros — **não inferir assinaturas**.
289
+ >
290
+ > - `com.funifier.engine.util.MustacheUtils.parse(template, valuesMap)` — substituição de variáveis Mustache (`patterns.md` §3).
291
+ > - `com.funifier.engine.mail.MailContext` — config SMTP da gamificação: `hostName`, `smtpPort`, `authUser`, `authPassword` (`patterns.md` §3).
292
+ > - `com.funifier.controller.Configuration.getCurrentConfiguration().getMailContext()` — obtém o `MailContext` atual (`patterns.md` §3).
316
293
 
317
294
  ---
318
295
 
319
- ## Resumo Rápido
320
-
321
- | Necessidade | O que usar |
322
- |------------|-----------|
323
- | Converter objeto para JSON | `JsonUtil.toJson(obj)` |
324
- | Converter JSON para objeto | `JsonUtil.fromJson(json, Class)` |
325
- | Gerar ID único | `Guid.newShortGuid()` |
326
- | Gerar código curto | `Guid.shortTimeMillis()` |
327
- | Calcular data com expressão | `DateUtil.fromKeyword("-0M-")` |
328
- | Fazer requisição HTTP | `Unirest.get/post/put/delete(url)` |
329
- | Enviar email | `EmailBuilder.startingBlank()...` |
330
- | Acessar MongoDB | `database.getCollection("nome")` |
296
+ ## 10. Resumo Rápido
297
+
298
+ | Necessidade | O que usar | Public Endpoint? |
299
+ |------------|-----------|------------------|
300
+ | Objeto JSON / JSON → objeto | `JsonUtil` | Sim |
301
+ | Gerar ID único / código curto | `Guid.newShortGuid()` / `shortTimeMillis()` | Trigger/Scheduler |
302
+ | Calcular data | `DateUtil.fromKeyword("-0M-")` | Sim |
303
+ | Requisição HTTP | `Unirest` | Não → `java.net.URL` |
304
+ | Enviar email | `EmailBuilder` | Não → trigger/scheduler |
305
+ | Hashear senha | `BCrypt` | Não → trigger |
306
+ | Acessar MongoDB | `database` / `getJongoConnection()` | Sim (via manager) |