funifier-mcp 0.3.17 → 0.3.19

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 (169) hide show
  1. package/.cursor/rules/funifier.mdc +3 -1
  2. package/.github/copilot-instructions.md +3 -1
  3. package/AGENTS.md +3 -1
  4. package/CHANGELOG.md +59 -0
  5. package/README.md +1 -1
  6. package/datasource-funifier-docs/.coverage.json +15 -5
  7. package/datasource-funifier-docs/.validation.json +77 -36
  8. package/datasource-funifier-docs/knowledge/guides/aggregates.md +13 -6
  9. package/datasource-funifier-docs/knowledge/guides/permission-audit.md +229 -0
  10. package/datasource-funifier-docs/knowledge/index.md +3 -2
  11. package/dist/cli/init.d.ts.map +1 -1
  12. package/dist/cli/init.js +3 -1
  13. package/dist/cli/init.js.map +1 -1
  14. package/dist/core/api-client.d.ts +2 -0
  15. package/dist/core/api-client.d.ts.map +1 -1
  16. package/dist/core/api-client.js +98 -47
  17. package/dist/core/api-client.js.map +1 -1
  18. package/dist/core/api-client.test.js +27 -0
  19. package/dist/core/api-client.test.js.map +1 -1
  20. package/dist/core/constants.d.ts +4 -0
  21. package/dist/core/constants.d.ts.map +1 -1
  22. package/dist/core/constants.js +8 -0
  23. package/dist/core/constants.js.map +1 -1
  24. package/dist/core/logger.d.ts +9 -0
  25. package/dist/core/logger.d.ts.map +1 -0
  26. package/dist/core/logger.js +50 -0
  27. package/dist/core/logger.js.map +1 -0
  28. package/dist/mcp/api-holder.test.d.ts +2 -0
  29. package/dist/mcp/api-holder.test.d.ts.map +1 -0
  30. package/dist/mcp/api-holder.test.js +45 -0
  31. package/dist/mcp/api-holder.test.js.map +1 -0
  32. package/dist/mcp/bundle.js +108 -105
  33. package/dist/mcp/check-update.d.ts +9 -0
  34. package/dist/mcp/check-update.d.ts.map +1 -1
  35. package/dist/mcp/check-update.js +35 -9
  36. package/dist/mcp/check-update.js.map +1 -1
  37. package/dist/mcp/check-update.test.js +36 -6
  38. package/dist/mcp/check-update.test.js.map +1 -1
  39. package/dist/mcp/doc-path.d.ts +11 -0
  40. package/dist/mcp/doc-path.d.ts.map +1 -0
  41. package/dist/mcp/doc-path.js +66 -0
  42. package/dist/mcp/doc-path.js.map +1 -0
  43. package/dist/mcp/doc-path.test.d.ts +2 -0
  44. package/dist/mcp/doc-path.test.d.ts.map +1 -0
  45. package/dist/mcp/doc-path.test.js +77 -0
  46. package/dist/mcp/doc-path.test.js.map +1 -0
  47. package/dist/mcp/index.js +19 -0
  48. package/dist/mcp/index.js.map +1 -1
  49. package/dist/mcp/resources/documentation.d.ts.map +1 -1
  50. package/dist/mcp/resources/documentation.js +7 -3
  51. package/dist/mcp/resources/documentation.js.map +1 -1
  52. package/dist/mcp/tools/_audit.d.ts +103 -0
  53. package/dist/mcp/tools/_audit.d.ts.map +1 -0
  54. package/dist/mcp/tools/_audit.js +241 -0
  55. package/dist/mcp/tools/_audit.js.map +1 -0
  56. package/dist/mcp/tools/_audit.test.d.ts +2 -0
  57. package/dist/mcp/tools/_audit.test.d.ts.map +1 -0
  58. package/dist/mcp/tools/_audit.test.js +412 -0
  59. package/dist/mcp/tools/_audit.test.js.map +1 -0
  60. package/dist/mcp/tools/_backup.d.ts +37 -3
  61. package/dist/mcp/tools/_backup.d.ts.map +1 -1
  62. package/dist/mcp/tools/_backup.js +142 -11
  63. package/dist/mcp/tools/_backup.js.map +1 -1
  64. package/dist/mcp/tools/_backup.test.js +195 -0
  65. package/dist/mcp/tools/_backup.test.js.map +1 -1
  66. package/dist/mcp/tools/_char-guard.d.ts +2 -1
  67. package/dist/mcp/tools/_char-guard.d.ts.map +1 -1
  68. package/dist/mcp/tools/_char-guard.js +10 -3
  69. package/dist/mcp/tools/_char-guard.js.map +1 -1
  70. package/dist/mcp/tools/_fetch-current.d.ts +2 -1
  71. package/dist/mcp/tools/_fetch-current.d.ts.map +1 -1
  72. package/dist/mcp/tools/_fetch-current.js +2 -74
  73. package/dist/mcp/tools/_fetch-current.js.map +1 -1
  74. package/dist/mcp/tools/_registry.d.ts +183 -0
  75. package/dist/mcp/tools/_registry.d.ts.map +1 -0
  76. package/dist/mcp/tools/_registry.js +88 -0
  77. package/dist/mcp/tools/_registry.js.map +1 -0
  78. package/dist/mcp/tools/_registry.test.d.ts +2 -0
  79. package/dist/mcp/tools/_registry.test.d.ts.map +1 -0
  80. package/dist/mcp/tools/_registry.test.js +103 -0
  81. package/dist/mcp/tools/_registry.test.js.map +1 -0
  82. package/dist/mcp/tools/_scope-engine.d.ts +40 -0
  83. package/dist/mcp/tools/_scope-engine.d.ts.map +1 -0
  84. package/dist/mcp/tools/_scope-engine.js +197 -0
  85. package/dist/mcp/tools/_scope-engine.js.map +1 -0
  86. package/dist/mcp/tools/_scope-engine.test.d.ts +2 -0
  87. package/dist/mcp/tools/_scope-engine.test.d.ts.map +1 -0
  88. package/dist/mcp/tools/_scope-engine.test.js +241 -0
  89. package/dist/mcp/tools/_scope-engine.test.js.map +1 -0
  90. package/dist/mcp/tools/database.d.ts +4 -0
  91. package/dist/mcp/tools/database.d.ts.map +1 -1
  92. package/dist/mcp/tools/database.js +23 -4
  93. package/dist/mcp/tools/database.js.map +1 -1
  94. package/dist/mcp/tools/database.test.js +19 -0
  95. package/dist/mcp/tools/database.test.js.map +1 -1
  96. package/dist/mcp/tools/delete.d.ts.map +1 -1
  97. package/dist/mcp/tools/delete.js +3 -98
  98. package/dist/mcp/tools/delete.js.map +1 -1
  99. package/dist/mcp/tools/execute.d.ts.map +1 -1
  100. package/dist/mcp/tools/execute.js +36 -4
  101. package/dist/mcp/tools/execute.js.map +1 -1
  102. package/dist/mcp/tools/execute.test.d.ts +2 -0
  103. package/dist/mcp/tools/execute.test.d.ts.map +1 -0
  104. package/dist/mcp/tools/execute.test.js +87 -0
  105. package/dist/mcp/tools/execute.test.js.map +1 -0
  106. package/dist/mcp/tools/get.d.ts.map +1 -1
  107. package/dist/mcp/tools/get.js +4 -93
  108. package/dist/mcp/tools/get.js.map +1 -1
  109. package/dist/mcp/tools/index.d.ts.map +1 -1
  110. package/dist/mcp/tools/index.js +42 -1
  111. package/dist/mcp/tools/index.js.map +1 -1
  112. package/dist/mcp/tools/list.d.ts.map +1 -1
  113. package/dist/mcp/tools/list.js +3 -91
  114. package/dist/mcp/tools/list.js.map +1 -1
  115. package/dist/mcp/tools/logs.d.ts.map +1 -1
  116. package/dist/mcp/tools/logs.js +5 -3
  117. package/dist/mcp/tools/logs.js.map +1 -1
  118. package/dist/mcp/tools/permissions.d.ts.map +1 -1
  119. package/dist/mcp/tools/permissions.js +68 -11
  120. package/dist/mcp/tools/permissions.js.map +1 -1
  121. package/dist/mcp/tools/permissions.test.js +268 -4
  122. package/dist/mcp/tools/permissions.test.js.map +1 -1
  123. package/dist/mcp/tools/read-doc.d.ts.map +1 -1
  124. package/dist/mcp/tools/read-doc.js +10 -28
  125. package/dist/mcp/tools/read-doc.js.map +1 -1
  126. package/dist/mcp/tools/save.d.ts.map +1 -1
  127. package/dist/mcp/tools/save.js +4 -81
  128. package/dist/mcp/tools/save.js.map +1 -1
  129. package/package.json +3 -2
  130. package/skills/funifier/SKILL.md +3 -1
  131. package/skills/funifier/references/audit-permissions.md +97 -0
  132. package/skills/funifier/references/configure-security.md +6 -0
  133. package/skills/funifier/references/create-action.md +7 -0
  134. package/skills/funifier/references/create-aggregate.md +99 -79
  135. package/skills/funifier/references/create-audit.md +8 -0
  136. package/skills/funifier/references/create-challenge.md +7 -0
  137. package/skills/funifier/references/create-competition.md +7 -0
  138. package/skills/funifier/references/create-crossword.md +6 -0
  139. package/skills/funifier/references/create-custom-object.md +6 -0
  140. package/skills/funifier/references/create-custom-page.md +6 -0
  141. package/skills/funifier/references/create-folder.md +7 -0
  142. package/skills/funifier/references/create-lastmile.md +6 -0
  143. package/skills/funifier/references/create-leaderboard.md +6 -0
  144. package/skills/funifier/references/create-level.md +7 -0
  145. package/skills/funifier/references/create-lottery.md +7 -0
  146. package/skills/funifier/references/create-mystery.md +6 -0
  147. package/skills/funifier/references/create-notification.md +6 -0
  148. package/skills/funifier/references/create-point.md +7 -0
  149. package/skills/funifier/references/create-quiz.md +7 -0
  150. package/skills/funifier/references/create-scheduler.md +6 -0
  151. package/skills/funifier/references/create-story.md +6 -0
  152. package/skills/funifier/references/create-swap.md +6 -0
  153. package/skills/funifier/references/create-trigger.md +8 -0
  154. package/skills/funifier/references/create-virtual-good.md +6 -0
  155. package/skills/funifier/references/create-webhook.md +6 -0
  156. package/skills/funifier/references/create-websocket.md +6 -0
  157. package/skills/funifier/references/create-widget.md +6 -0
  158. package/skills/funifier/references/date-handling.md +6 -0
  159. package/skills/funifier/references/debug.md +6 -0
  160. package/skills/funifier/references/help.md +6 -0
  161. package/skills/funifier/references/implement-frontend.md +7 -0
  162. package/skills/funifier/references/import-csv.md +6 -0
  163. package/skills/funifier/references/manage-indexes.md +6 -0
  164. package/skills/funifier/references/manage-player.md +7 -0
  165. package/skills/funifier/references/manage-team.md +6 -0
  166. package/skills/funifier/references/query-aggregate.md +111 -0
  167. package/skills/funifier/references/upload-file.md +6 -0
  168. package/datasource-funifier-docs/.search-index.json +0 -58758
  169. package/datasource-funifier-docs/.skills-map.json +0 -141
@@ -38,32 +38,7 @@ const zod_1 = require("zod");
38
38
  const fs = __importStar(require("fs"));
39
39
  const _fetch_current_1 = require("./_fetch-current");
40
40
  const _merge_1 = require("./_merge");
41
- const RESOURCE_TYPES = [
42
- "trigger",
43
- "scheduler",
44
- "aggregate",
45
- "websocket",
46
- "widget",
47
- "custom-page",
48
- "public-endpoint",
49
- "challenge-aggregate",
50
- "auth-module",
51
- "ai-knowledge",
52
- "audit",
53
- "action",
54
- "challenge",
55
- "point",
56
- "level",
57
- "leaderboard",
58
- "quiz",
59
- "virtual-good-catalog",
60
- "virtual-good-item",
61
- "folder",
62
- "folder-content",
63
- "folder-content-type",
64
- "folder-log",
65
- ];
66
- const GROOVY_TYPES = new Set(["trigger", "scheduler", "aggregate", "websocket", "public-endpoint", "auth-module"]);
41
+ const _registry_1 = require("./_registry");
67
42
  const COMPANION_FIELDS = {
68
43
  html: ".html",
69
44
  css: ".css",
@@ -72,7 +47,7 @@ const COMPANION_FIELDS = {
72
47
  };
73
48
  function mergeCompanions(jsonPath, type, doc) {
74
49
  const base = jsonPath.replace(/\.json$/, "");
75
- const scriptExt = GROOVY_TYPES.has(type) ? ".script.groovy" : ".script.js";
50
+ const scriptExt = (0, _registry_1.isGroovyType)(type) ? ".script.groovy" : ".script.js";
76
51
  const fields = { ...COMPANION_FIELDS, script: scriptExt };
77
52
  const merged = { ...doc };
78
53
  for (const [field, ext] of Object.entries(fields)) {
@@ -163,64 +138,12 @@ function sanitizeChallenge(data) {
163
138
  }
164
139
  return d;
165
140
  }
166
- async function dispatchSave(api, type, data) {
167
- switch (type) {
168
- case "trigger":
169
- return await api.saveTrigger(data);
170
- case "scheduler":
171
- return await api.saveScheduler(data);
172
- case "aggregate":
173
- return await api.saveAggregate(data);
174
- case "websocket":
175
- return await api.saveWebsocket(data, !data._id);
176
- case "widget":
177
- return await api.saveWidget(data);
178
- case "custom-page":
179
- return await api.saveCustomPage(data);
180
- case "public-endpoint":
181
- return await api.savePublicEndpoint(data);
182
- case "challenge-aggregate":
183
- return await api.saveChallengeAggregate(data);
184
- case "auth-module":
185
- return await api.saveAuthModule(data, !data._id);
186
- case "ai-knowledge":
187
- return await api.saveAiKnowledge(data);
188
- case "audit":
189
- return await api.saveAudit(data);
190
- case "action":
191
- return await api.saveAction(data);
192
- case "challenge":
193
- return await api.saveChallenge(data);
194
- case "point":
195
- return await api.savePoint(data);
196
- case "level":
197
- return await api.saveLevel(data);
198
- case "leaderboard":
199
- return await api.saveLeaderboard(data);
200
- case "quiz":
201
- return await api.saveQuiz(data);
202
- case "virtual-good-catalog":
203
- return await api.saveVirtualGoodCatalog(data);
204
- case "virtual-good-item":
205
- return await api.saveVirtualGoodItem(data);
206
- case "folder":
207
- return await api.saveFolder(data);
208
- case "folder-content":
209
- return await api.saveFolderContent(data);
210
- case "folder-content-type":
211
- return await api.saveFolderContentType(data);
212
- case "folder-log":
213
- return await api.saveFolderLog(data);
214
- default:
215
- throw new Error(`Unknown resource type: ${type}`);
216
- }
217
- }
218
141
  function registerSaveTool(server, apiHolder) {
219
142
  server.registerTool("funifier_save", {
220
143
  title: "Save Funifier Resource",
221
144
  description: "Create or update a Funifier resource. On update (when `_id` is present in the payload), the current resource is fetched and any fields missing from the payload are preserved — you only need to send the fields you want to change. To clear a field, send it explicitly as `null`. Array and object fields are replaced wholesale when present in the payload.",
222
145
  inputSchema: {
223
- type: zod_1.z.enum(RESOURCE_TYPES).describe("The resource type"),
146
+ type: zod_1.z.enum(_registry_1.SAVE_TYPES).describe("The resource type"),
224
147
  payload: zod_1.z.string().optional().describe("JSON string of the resource payload. On update, send only the fields you want to change (plus `_id`). Use `file` instead when the payload is too large to pass inline."),
225
148
  file: zod_1.z.string().optional().describe("Path to a JSON file containing the resource payload. Use this when the payload is too large to pass inline (e.g. a file previously written by funifier_get)."),
226
149
  },
@@ -252,7 +175,7 @@ function registerSaveTool(server, apiHolder) {
252
175
  }
253
176
  // if current is null: _id is user-defined for a new resource — create as-is
254
177
  }
255
- const result = await dispatchSave(api, type, toSave);
178
+ const result = await (0, _registry_1.saveResource)(api, type, toSave);
256
179
  // Funifier sometimes returns 200/201 with an error body
257
180
  if (result?.status === "ERROR" || result?.status === "error" ||
258
181
  result?.errorCode != null || result?.errorMessage != null) {
@@ -1 +1 @@
1
- {"version":3,"file":"save.js","sourceRoot":"","sources":["../../../src/mcp/tools/save.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"save.js","sourceRoot":"","sources":["../../../src/mcp/tools/save.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "funifier-mcp",
3
- "version": "0.3.17",
3
+ "version": "0.3.19",
4
4
  "description": "Funifier AI toolkit — MCP server, API client, and Claude Code skills for the Funifier gamification platform",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -16,6 +16,7 @@
16
16
  ".github/copilot-instructions.md",
17
17
  ".cursor/rules/funifier.mdc",
18
18
  "README.md",
19
+ "CHANGELOG.md",
19
20
  "LICENSE"
20
21
  ],
21
22
  "repository": {
@@ -72,4 +73,4 @@
72
73
  "engines": {
73
74
  "node": ">=18"
74
75
  }
75
- }
76
+ }
@@ -35,7 +35,8 @@ Then read a result with `funifier_read_doc path=<path>`.
35
35
  |-------------|-----------|
36
36
  | Create a Funifier trigger — guided workflow from entity/event selection to Groovy code generation | `references/create-trigger.md` |
37
37
  | Create a Funifier scheduler — guided workflow from naming and cron expression to Groovy code generation | `references/create-scheduler.md` |
38
- | Create a Funifier prepared aggregate guided workflow for building MongoDB aggregate pipelines for reports and dashboards | `references/create-aggregate.md` |
38
+ | Run an ad-hoc MongoDB aggregate (one-off query) on a Funifier collection via POST /v3/database/{collection}/aggregate for reports and exploration, without saving a resource | `references/query-aggregate.md` |
39
+ | Create/edit a Funifier prepared aggregate — a saved pipeline with _id, $param placeholders, optional Groovy script, cache and execution via POST /v3/find/{id}; for reusable dashboards and parametrized reports | `references/create-aggregate.md` |
39
40
  | Create, edit, or query Date fields safely via REST, funifier_database, triggers, schedulers, aggregate, and prepared aggregate; use whenever a payload or filter contains dates | `references/date-handling.md` |
40
41
  | Create a Funifier challenge — missions with action rules and point rewards | `references/create-challenge.md` |
41
42
  | Create a Funifier action — define trackable player behaviors with attributes | `references/create-action.md` |
@@ -68,6 +69,7 @@ Then read a result with `funifier_read_doc path=<path>`.
68
69
  | Import or export Funifier platform data via CSV — bulk player import, performance export, and cross-system data migration; use when loading or extracting large datasets, not for individual record CRUD or media file uploads (use funifier-upload-file) | `references/import-csv.md` |
69
70
  | Upload files to Funifier — images and documents for player avatars, challenge resources, and visual assets; use when adding media to the platform, not for CSV data import (use funifier-import-csv) or static frontend hosting (use funifier-implement-frontend) | `references/upload-file.md` |
70
71
  | Create, list, and drop MongoDB single-field indexes on Funifier collections via the REST API. Composite (multi-field) indexes are NOT supported by this endpoint — see Limitation section. | `references/manage-indexes.md` |
72
+ | Cross-check a project's Funifier API calls against the live security document — scan code for usage, build an evidence-backed manifest, run the deterministic audit engine, and report missing scopes, excess tokens, and static danger findings; use when debugging 401s, auditing minimum privilege, or verifying permissions before deploying; audit is read-only and never changes any configuration | `references/audit-permissions.md` |
71
73
 
72
74
  ## Documented Modules
73
75
 
@@ -0,0 +1,97 @@
1
+ # funifier-audit-permissions
2
+
3
+ Cross-check a project's Funifier API calls against the live security document — scan code for usage, build an evidence-backed manifest, run the deterministic audit engine, and report missing scopes, excess tokens, and static danger findings; use when debugging 401s, auditing minimum privilege, or verifying permissions before deploying; audit is read-only and never changes any configuration
4
+
5
+ ---
6
+
7
+ ## Before starting — find relevant docs
8
+
9
+ Use the `funifier_search_docs` MCP tool to load only what you need:
10
+
11
+ ```
12
+ funifier_search_docs "audit permissions security scope 401 missing-scope excess-token danger manifest bearer basic app-secret role least-privilege"
13
+ ```
14
+
15
+ Then read the most relevant results with `funifier_read_doc path=<path>`.
16
+
17
+ ## Primary docs for this skill
18
+
19
+ If search returns insufficient results, read these directly:
20
+
21
+ - `funifier_read_doc path=guides/permission-audit`
22
+ - `funifier_read_doc path=modules/security`
23
+
24
+ ## Steps
25
+
26
+ ## Regras críticas
27
+
28
+ - **O audit é read-only.** Nenhuma configuração é alterada. O MCP apenas lê o documento de segurança e avalia o manifest.
29
+ - **Bearer tokens embtem o scope no login.** Corrigir o role não invalida tokens existentes — o jogador precisa fazer login novamente.
30
+ - **Excess findings podem ser necessários** a consumidores fora deste manifest. Verifique antes de remover qualquer token.
31
+ - **Low-confidence entries** (URLs dinâmicas ou wrappers): use `"confidence": "low"` e um path com o prefixo mais específico possível. Nunca omita chamadas suspeitas.
32
+
33
+ ---
34
+
35
+ ## Steps
36
+
37
+ ### 1. Descobrir chamadas Funifier no projeto
38
+
39
+ Procure no código todas as chamadas à API Funifier (endpoints, métodos HTTP e mecanismo de auth):
40
+
41
+ - **Com GitNexus indexado:** `gitnexus_query("funifier API calls")` para localizar call sites
42
+ - **Fallback (busca em código):** grep por `/v3/`, `funifier`, `apiKey`, `app_secret`, `Authorization`
43
+ - Para cada chamada, registre: `method`, `path`, `auth context` (ver tabela em `guides/permission-audit.md` §2), e `file:line` como `evidence`
44
+ - Classifique o auth:
45
+ - Sem secret / token público → `"public"`
46
+ - Player Bearer → `"player"`
47
+ - App secret em config/env → `"app:<name>"` (use o `name` da entrada em `apps[]`)
48
+
49
+ ### 2. Montar o manifest
50
+
51
+ Construa o JSON seguindo o schema de `guides/permission-audit.md` §3. Exemplo mínimo:
52
+
53
+ ```json
54
+ {
55
+ "version": 1,
56
+ "entries": [
57
+ { "method": "GET", "path": "/v3/player/me", "auth": "player", "evidence": "src/api.ts:12" },
58
+ { "method": "POST", "path": "/v3/action/log", "auth": "player", "evidence": "src/events.ts:58" },
59
+ { "method": "POST", "path": "/v3/player", "auth": "app:backend", "evidence": "workers/sync.ts:34" },
60
+ { "method": "GET", "path": "/v3/database/orders", "auth": "app:backend", "evidence": "workers/sync.ts:80" }
61
+ ]
62
+ }
63
+ ```
64
+
65
+ Para chamadas com URL dinâmica: use o prefixo mais específico e defina `"confidence": "low"`.
66
+
67
+ ### 3. Executar o audit
68
+
69
+ ```
70
+ funifier_permissions action=audit data=<manifest JSON>
71
+ ```
72
+
73
+ O resultado inclui:
74
+ - `missing`: chamadas que seriam negadas — 401 em produção. Campo `requiredTokens` indica o token mínimo.
75
+ - `excess`: tokens concedidos que nenhuma entrada requer. Campo `narrowingSuggestion` para broad tokens.
76
+ - `danger`: riscos estáticos no documento de segurança (independentes do manifest).
77
+ - `manual-review`: tokens não verificáveis por análise de paths (`cross_domain`, `write_upload`, etc.).
78
+ - `missing-principal`: auth context referenciado no manifest não existe no documento de segurança.
79
+
80
+ ### 4. Apresentar o relatório e encaminhar remediação
81
+
82
+ Apresente os findings agrupados por severidade (`missing` primeiro). Para cada `missing`:
83
+ - Indique o token exato necessário (`requiredTokens`), a chamada e a evidência.
84
+ - **Não aplique a correção automaticamente.** Apresente a ação sugerida ao utilizador e aguarde aprovação.
85
+ - Quando aprovado: `funifier_permissions action=save_security_role` ou `save_api_app` (cada mutação cria backup automático).
86
+
87
+ Para `excess`: adverta que o token pode ser necessário a consumidores fora deste manifest antes de sugerir remoção.
88
+
89
+ Para `danger`: explique o risco e sugira remoção ou restrição do scope afetado como ação separada.
90
+
91
+ ## Verified References
92
+
93
+ | Claim | Status | Evidence |
94
+ |-------|--------|----------|
95
+ | SecurityFilter.doFilter evaluates (method, path) by computing verb (GET→read, POST/PUT→write, DELETE→delete) and entity_full (path after /v3/ with slash→underscore), then matching scope tokens in order: {verb}_all, exact {verb}_{entity_full}, fallback {verb}_{prefix}_all minus-1 and minus-2 trailing segments | ✓ verified | Class:src/main/java/com/funifier/rest/v3/filter/SecurityFilter.java:SecurityFilter |
96
+ | DatabaseRest requires the literal 'database' scope keyword on ALL /v3/database handlers including GET operations — grammar tokens such as read_all alone are insufficient; this is enforced within SecurityFilter.doFilter before requests reach DatabaseRest handlers | ✓ verified | Method:src/main/java/com/funifier/rest/v3/filter/SecurityFilter.java:SecurityFilter.doFilter#3 |
97
+ | Bearer tokens embed the player's role scope string at login time; role scope changes only affect sessions created after the change — existing live Bearer tokens carry the scope at their issuance time | ✓ verified | Class:src/main/java/com/funifier/rest/v3/filter/SecurityFilter.java:SecurityFilter |
@@ -112,3 +112,9 @@ funifier_permissions action=restore_backup backup_path=<path retornado por list_
112
112
  O restore valida que o `serverUrl` do snapshot coincide com a conexão atual — não aplique backup de outro tenant. O próprio restore também gera um snapshot prévio, permitindo desfazer o rollback.
113
113
 
114
114
  Variáveis opcionais: `FUNIFIER_PROJECT_ROOT` (diretório do projeto; definida nos configs gerados pelo `init`) e `FUNIFIER_BACKUP_ROOT` (substitui `.funifier/backups/` por outro diretório). Snapshots não expiram automaticamente — remova arquivos antigos manualmente quando necessário.
115
+
116
+ ## Verified References
117
+
118
+ | Claim | Status | Evidence |
119
+ |-------|--------|----------|
120
+
@@ -91,3 +91,10 @@ funifier_list type=action search=<_id>
91
91
  ```
92
92
 
93
93
  Do NOT use `funifier_logs` — that is only for triggers and schedulers.
94
+
95
+ ## Verified References
96
+
97
+ | Claim | Status | Evidence |
98
+ |-------|--------|----------|
99
+ | ActionLog is the entity class recording each player action event with fields actionId, userId, attributes, time, and id | ✓ verified | Class:src/main/java/com/funifier/engine/action/ActionLog.java:ActionLog |
100
+ | ActionManager handles action registration and dispatching in funifier-service | ✓ verified | Class:src/main/java/com/funifier/engine/action/ActionManager.java:ActionManager |
@@ -1,6 +1,6 @@
1
1
  # funifier-create-aggregate
2
2
 
3
- Create a Funifier prepared aggregate — guided workflow for building MongoDB aggregate pipelines for reports and dashboards
3
+ Create/edit a Funifier prepared aggregate — a saved pipeline with _id, $param placeholders, optional Groovy script, cache and execution via POST /v3/find/{id}; for reusable dashboards and parametrized reports
4
4
 
5
5
  ---
6
6
 
@@ -48,7 +48,7 @@ Note que `aggregate` é uma **string** contendo JSON serializado (com `\n` e `\"
48
48
  Use the `funifier_search_docs` MCP tool to load only what you need:
49
49
 
50
50
  ```
51
- funifier_search_docs "aggregate mongodb pipeline report dashboard query prepared"
51
+ funifier_search_docs "aggregate mongodb pipeline prepared dashboard param script find reusable"
52
52
  ```
53
53
 
54
54
  Then read the most relevant results with `funifier_read_doc path=<path>`.
@@ -63,118 +63,138 @@ If search returns insufficient results, read these directly:
63
63
 
64
64
  ## Steps
65
65
 
66
- > **Prepared aggregate** = pipeline MongoDB salvo na plataforma com `_id` e executado por ID via `POST /v3/find/<id>`, com parâmetros dinâmicos (`"$param:nome"`). Diferente do aggregate **ad-hoc** (`POST /v3/database/{collection}/aggregate`), usado para testar pipelines.
66
+ > **Prepared aggregate** = pipeline MongoDB **salvo** na plataforma (coleção `prepared_aggregate`) com `_id`, parâmetros dinâmicos (`"$param:nome"`) e um `script` Groovy opcional, executado por ID via `POST /v3/find/<id>`. Use para dashboards e relatórios **reutilizáveis**. Para uma consulta **pontual sem salvar**, use a skill `funifier-query-aggregate` (ad-hoc).
67
67
 
68
- ### Coleções principais
68
+ > ⚠️ **"Salvo" ≠ "funcionando".** O `funifier_save type=aggregate` persiste via `PUT /v3/database/prepared_aggregate` (upsert genérico de banco) e **NÃO compila** o `script`. Um script quebrado é "salvo com sucesso" e só falha — silenciosamente — na execução. Por isso o fluxo abaixo é **montar → salvar → verificar**, nunca só salvar.
69
69
 
70
- | Coleção | Conteúdo chave |
71
- |---|---|
72
- | `achievement` | Conquistas — `type`: 0=Point, 1=Challenge, 2=VirtualGood, 3=Level |
73
- | `action_log` | Ações executadas — `actionId`, `userId`, `attributes`, `time` |
74
- | `player` | Jogadores — `_id`, `name`, `teams`, `extra` |
75
- | `challenge` | Desafios — `_id`, `challenge`, `rules`, `points` |
76
- | `point_category` | Tipos de ponto — `_id`, `category`, `shortName` |
77
- | `catalog_item` | Loja virtual — `_id`, `catalogId`, `name`, `requires` |
70
+ ### 1. Definir a consulta e montar o pipeline
78
71
 
79
- Se o pipeline filtrar ou criar campos de data, leia também `references/date-handling.md` antes de montar o payload.
72
+ - Qual coleção, filtro, agrupamento, ordenação e limite? Quais valores serão **parâmetros** (`$param`)?
73
+ - Monte/teste o pipeline como uma consulta **ad-hoc** primeiro (skill `funifier-query-aggregate`) — não reensine a execução direta aqui. As relações de coleção para `$lookup` estão lá e em `aggregates.md` §3.
74
+ - Confira se já existe: `funifier_list type=aggregate search=<titulo>`.
80
75
 
81
- ### Expressões de data Funifier
76
+ ### 2. Campos do recurso
82
77
 
83
- Para regras completas de criação/edição/consulta de datas via REST, triggers, schedulers, aggregate e prepared aggregate, leia `references/date-handling.md`.
78
+ Todos embasados em `PreparedAggregate` (funifier-service). Apenas `_id`, `title`, `collection`, `aggregate` são essenciais; o resto é opcional.
84
79
 
85
- | Expressão | Significado |
80
+ | Campo | Semântica |
86
81
  |---|---|
87
- | `{"$date": "-0d-"}` | Início do dia atual |
88
- | `{"$date": "-0M-"}` | Início do mês atual |
89
- | `{"$date": "-0M+"}` | Fim do mês atual |
90
- | `{"$date": "-0y-"}` | Início do ano atual |
91
- | `{"$date": "-1d-"}` | Início do dia anterior |
82
+ | `_id` | Identificador do recurso (usado em `POST /v3/find/<id>`). |
83
+ | `title` | Nome legível. |
84
+ | `description` | Descrição livre (opcional). |
85
+ | `collection` | Coleção-base sobre a qual o pipeline roda. |
86
+ | `aggregate` | **String** contendo um array JSON válido (o pipeline). Ver §3. |
87
+ | `script` | Groovy opcional `void prepare(aggregations, params)` (`""` se não precisar). Ver §6. |
88
+ | `timeout` | Sobrescreve o timeout padrão de **5s** do script (em segundos). |
89
+ | `cache` | Expressão de duração Funifier (ex.: `"30m"`, `"3h"`) — TTL do resultado em cache, servido pelo mesmo `POST /v3/find/<id>`. |
90
+ | `cache_before_find` | Aplica o cache antes do find (caso avançado). |
91
+ | `parent` | Consulta o resultado **em cache de outro find** em vez de uma coleção (find-sobre-find, **um nível**; o parent deve usar `collection`). |
92
92
 
93
- **Importante:** em aggregate direto e prepared aggregate, prefira expressões relativas Funifier dentro de `$date` (`-0M-`, `-0M+`) ou timestamps em milissegundos para datas absolutas. Para datas absolutas parametrizadas em prepared aggregate, normalize no `script` com `DateUtil.parse(...)` e substitua diretamente em `$gte`/`$lte`.
93
+ ### 3. Formato do campo `aggregate` (string JSON)
94
94
 
95
- ---
95
+ O campo `aggregate` é uma **`String`** lida na execução com `JsonUtil.fromJson(aggregate, List.class)`. **Só importa a validade do JSON** — indentação, `\n` e minificação são irrelevantes. Construa um array nativo e serialize com `JSON.stringify(pipeline)`, deixando o escape com o MCP.
96
96
 
97
- ## Steps
97
+ > ⚠️ **Não envie um array JSON nativo** em `aggregate` — o campo da entidade é `String`; um array nativo gera um recurso que falha na execução. Minificado em uma linha **é aceito** (não existe regra de "identado, nunca minificado").
98
98
 
99
- ### 1. Identificar a necessidade
99
+ Exemplo (identado por legibilidade — minificado também funciona):
100
+ ```json
101
+ {
102
+ "_id": "top_players_month",
103
+ "title": "Top Players Month",
104
+ "collection": "achievement",
105
+ "aggregate": "[{\"$match\":{\"type\":0,\"item\":\"xp\"}},{\"$group\":{\"_id\":\"$player\",\"total\":{\"$sum\":\"$total\"}}},{\"$sort\":{\"total\":-1}},{\"$limit\":10}]",
106
+ "script": "",
107
+ "cache": "30m"
108
+ }
109
+ ```
100
110
 
101
- - Qual collection tem os dados? (ver tabela acima)
102
- - Qual o filtro? (período, jogador, tipo de conquista)
103
- - Qual o agrupamento? (por jogador, por dia, por equipe)
104
- - Qual ordenação e limite?
111
+ > Via `funifier_save type=aggregate file=...`, o pipeline pode vir do arquivo companheiro `.pipeline.json` — o MCP serializa e escapa para você.
105
112
 
106
- ### 2. Verificar se já existe
113
+ ### 4. Parâmetros `$param`
107
114
 
108
- ```
109
- funifier_list type=aggregate search=<titulo>
110
- ```
115
+ - Um placeholder deve ser o **valor de string JSON inteiro**: `"$param:nome"`. A substituição é a **nível de valor** (sem concatenação/interpolação de substring) e o valor assume o **tipo** do param: string, número, `Long` (millis), `Date`, array ou objeto.
116
+ - **Param ausente vira `null`** → filtro silenciosamente não casa nada. Confirme os nomes esperados com `funifier_execute type=aggregate id=<id> mode=params` (varredura literal de `"$param:NOME"` na string salva).
117
+ - Avançado: pode-se injetar um **sub-pipeline**, nome de **coleção** ou `Map`/`List` via param (ex.: `"$param:collection"`, `"$param:pipelineSearch"`) quando o `script` faz `params.put` de um valor real.
111
118
 
112
- ### 3. Construir e testar o pipeline
119
+ ### 5. Datas parametrizadas
113
120
 
114
- Top 10 jogadores com mais pontos no mês:
115
- ```json
116
- [
117
- {"$match": {"type": 0, "item": "xp", "time": {"$gte": {"$date": "-0M-"}, "$lte": {"$date": "-0M+"}}}},
118
- {"$group": {"_id": "$player", "total": {"$sum": "$total"}}},
119
- {"$sort": {"total": -1}},
120
- {"$lookup": {"from": "player", "localField": "_id", "foreignField": "_id", "as": "p"}},
121
- {"$unwind": "$p"},
122
- {"$project": {"_id": 1, "player": "$p.name", "total": 1}},
123
- {"$limit": 10}
124
- ]
125
- ```
121
+ A gramática `{"$date": "-0M-"}` (relativa, não-parametrizada) pode ir **direto** no pipeline salvo — detalhada em `aggregates.md` §4 (dono único; `funifier_read_doc path=guides/aggregates`). Para uma data **dinâmica vinda de param**, o padrão real é:
126
122
 
127
- Testar diretamente antes de registrar:
128
123
  ```
129
- POST /v3/database/achievement/aggregate
124
+ pipeline: { "$match": { "time": { "$gte": {"$date": "$param:start"}, "$lte": {"$date": "$param:end"} } } }
125
+ script: params.put("start", startDate.getTime()) // millis (Long) — ou injete um Date
130
126
  ```
131
127
 
132
- ### 4. Registrar como Prepared Aggregate
128
+ Omitir o param de data na execução → o engine substitui por `null` e o filtro não casa nada. Ver também a skill `funifier-date-handling`.
133
129
 
134
- **Formatação obrigatória:** o campo `aggregate` é o pipeline serializado como **string identada**, com `\n` ao fim de cada linha (equivalente a `JSON.stringify(pipeline, null, 4)`) — **nunca** minificado em uma linha única. O `script` Groovy também preserva indentação e `\n`. Os escapes (`\"`, `\\`) seguem a seção "Formato do payload" acima.
130
+ ### 6. Script Groovy `prepare()` (opcional)
135
131
 
136
- ```json
137
- {
138
- "_id": "top_players_month",
139
- "title": "Top Players Month",
140
- "collection": "achievement",
141
- "aggregate": "[\n {\n \"$match\": {\n \"type\": 0,\n \"item\": \"xp\"\n }\n },\n {\n \"$group\": {\n \"_id\": \"$player\",\n \"total\": {\n \"$sum\": \"$total\"\n }\n }\n },\n {\n \"$sort\": {\n \"total\": -1\n }\n },\n {\n \"$limit\": 10\n }\n]",
142
- "script": ""
132
+ Se o pipeline só usa placeholders `"$param:nome"`, `script: ""` é válido — não precisa de `prepare()`. Quando precisar de lógica (resolver janela de datas, guardas), o contrato é:
133
+
134
+ - **Assinatura de entrada:** `void prepare(aggregations, params)`. Métodos auxiliares extras são permitidos.
135
+ - **Ambiente:** roda dentro de uma `class FunifierTrigger` gerada, que já importa `DateUtil`, `JsonUtil`, `manager` (`ManagerFactory`), as entidades, e o default `java.util.*` do Groovy. O `context` expõe **apenas** `player`. `println(...)` é capturado (visível no `script_outputs` do analyze). **Timeout padrão 5s** (sobrescrevível via `timeout`).
136
+ - **Sandbox:** compilado sob um whitelist de tokens de operador (`SecureASTCustomizer` + `TriggerExpressionChecker`) — **sem ternário `?:`**, **sem bitwise**. Mantenha a lógica simples.
137
+
138
+ Exemplo (resolve janela do mês e guarda usuário inativo):
139
+ ```groovy
140
+ void prepare(aggregations, params) {
141
+ params.put("start", DateUtil.fromKeyword("-0M-").getTime());
142
+ params.put("end", DateUtil.fromKeyword("-0M+").getTime());
143
+ String player = context.get("player");
144
+ if (player == null || isInactive(player)) {
145
+ params.put("player", "__none__"); // sentinela → resultado vazio controlado
146
+ } else {
147
+ params.put("player", player);
148
+ }
143
149
  }
144
- ```
145
150
 
146
- ```
147
- funifier_save type=aggregate payload=<json>
151
+ boolean isInactive(String player) {
152
+ def p = manager.getJongoConnection().getCollection("player").findOne("{_id:#}", player).as(Map.class);
153
+ return p == null;
154
+ }
148
155
  ```
149
156
 
150
- ### 5. Validar
157
+ ### 7. Antes de salvar: índices e forma da query
158
+
159
+ 1. Liste os campos que dirigem o plano: filtros de `$match`, campos de `$sort`, e `localField`/`foreignField` de cada `$lookup` (atenção ao `foreignField` na coleção `from`).
160
+ 2. Cheque/crie índices: `funifier_index action=list collection=<coll>`; crie os single-field faltantes com `funifier_index action=create`. Índice **composto** (ex.: `{player:1,time:-1}`) → REST é single-field apenas; use o caminho Groovy `createIndex(...append...)` (ver skill `funifier-manage-indexes`).
161
+ 3. Boas práticas: `$match` cedo · reduzir com `$project`/`$match` antes do `$lookup` · `$sort` seguido de `$limit` · cuidado com explosão do `$unwind` · `$lookup.foreignField` indexado.
162
+ 4. Prepared usa `allowDiskUse(true)`; ainda assim raciocine a cobertura de índice sobre o **`aggregate_step_3`** (pipeline já com `$param` resolvido), pois os valores de param mudam o filtro efetivo. Ao **editar** um aggregate, refaça esta checagem nos estágios alterados.
163
+
164
+ ### 8. Salvar
151
165
 
152
166
  ```
153
- funifier_list type=aggregate search=<titulo>
167
+ funifier_save type=aggregate payload=<json>
154
168
  ```
155
169
 
156
- ### 6. Executar o Prepared Aggregate
170
+ Isto persiste, mas **não verifica** nada (ver aviso no topo). "Salvo" é um estado; "verificado funcionando" é outro, alcançado no passo 9.
157
171
 
158
- **Endpoint correto:** `POST /v3/find/<id>` com os parâmetros no corpo JSON.
172
+ ### 9. Verificar (obrigatório)
159
173
 
160
- > ⚠️ NÃO use `GET /v3/database/aggregate/{id}` retorna null/405 silenciosamente, sem mensagem de erro. O endpoint de execução foge do padrão CRUD da plataforma.
174
+ Use os modos do `funifier_execute` (o REST cru é fallback):
161
175
 
162
- Via MCP (`params` é uma string JSON):
163
176
  ```
164
- funifier_execute type=aggregate id=<id> params={"player":"abc"}
177
+ funifier_execute type=aggregate id=<id> mode=params # nomes de $param esperados
178
+ funifier_execute type=aggregate id=<id> mode=analyze params={...} # dry-run: NÃO roda no Mongo
179
+ funifier_execute type=aggregate id=<id> params={...} # mode=run (default): resultado real
165
180
  ```
166
181
 
167
- Via frontend:
168
- ```js
169
- api.post('/v3/find/<id>', { player: 'abc' })
170
- ```
182
+ O `mode=analyze` é uma **inspeção (dry-run)** — compila/roda o `script`, aplica a substituição de `$param` e devolve:
183
+
184
+ | Campo | Conteúdo |
185
+ |---|---|
186
+ | `script_exceptions` | Erros de compilação/execução do Groovy — **vazio = script ok** |
187
+ | `script_outputs` | Saídas de `println` do `prepare()` |
188
+ | `obj` | A **definição salva** (a entidade, não os resultados) |
189
+ | `aggregate_step_2` | Pipeline **após** o `prepare()` |
190
+ | `aggregate_step_3` | Pipeline **após** a substituição dos `"$param:nome"` |
191
+
192
+ Diagnóstico: resultado de `mode=run` vazio **ou** recurso com `script` não-vazio → rode `mode=analyze` e leia `script_exceptions` (script quebrado) e `aggregate_step_3` (se um param virou `null`, o `$match` não casa nada — isso distingue "script quebrado" de "resultado legitimamente vazio").
193
+
194
+ > ⚠️ NÃO execute via `GET /v3/database/aggregate/{id}` — retorna null/405 silenciosamente. A execução é `POST /v3/find/<id>` (corpo JSON, nunca query string). Via frontend: `api.post('/v3/find/<id>', { player: 'abc' })`.
171
195
 
172
- | Regra | Detalhe |
173
- |-------|---------|
174
- | Método HTTP | POST obrigatório |
175
- | Params | No corpo JSON — não na query string |
176
- | Substituição | Cada chave do corpo substitui `"$param:<chave>"` no pipeline diretamente |
177
- | `context` no Groovy | Só expõe o player autenticado — `context.get("outro")` retorna `null` |
178
- | Script vazio | Se o pipeline só usa `"$param:nome"`, o `script` pode ser `""` — não precisa de `prepare()` |
196
+ ## Verified References
179
197
 
180
- Se o resultado vier vazio ou inesperado: `GET /v3/find/<id>/params` lista os params que o pipeline espera, e `POST /v3/prepared/aggregate/<id>/analyze` (mesmo corpo da execução) retorna outputs/exceções do script e o resultado de cada etapa do pipeline (`aggregate_step_N`) — veja `references/debug.md`.
198
+ | Claim | Status | Evidence |
199
+ |-------|--------|----------|
200
+ | DatabaseManager provides MongoDB connection and collection access for aggregate queries in Groovy scripts | ✓ verified | Class:src/main/java/com/funifier/engine/database/DatabaseManager.java:DatabaseManager |
@@ -113,3 +113,11 @@ Filtros combináveis em `$match`: `user`/`login` (ator), `type` (`studio`/`playe
113
113
  ### 6. Exclusão (cuidado)
114
114
 
115
115
  `funifier_delete type=audit id=<id>` remove a config **e todos os seus logs em cascata**. Confirme com o usuário antes.
116
+
117
+ ## Verified References
118
+
119
+ | Claim | Status | Evidence |
120
+ |-------|--------|----------|
121
+ | Audit config fields are _id, title, active, entity, event, clean, type with event constants create/update/delete and type constants studio/player/all | ✓ verified | Class:src/main/java/com/funifier/engine/audit/Audit.java:Audit |
122
+ | AuditManager.log only writes an AuditLog when an active Audit matches entity+event and the config type matches the operation origin | ✓ verified | Class:src/main/java/com/funifier/engine/audit/AuditManager.java:AuditManager |
123
+ | clearExpiredLogs purges audit_log entries older than each config's clean retention and is invoked from AsyncProcessor | ✓ verified | Method:src/main/java/com/funifier/engine/audit/AuditManager.java:AuditManager.clearExpiredLogs#0 |
@@ -114,3 +114,10 @@ funifier_get type=challenge id=<_id>
114
114
  ```
115
115
 
116
116
  Não use `funifier_logs` — isso é só para triggers e schedulers.
117
+
118
+ ## Verified References
119
+
120
+ | Claim | Status | Evidence |
121
+ |-------|--------|----------|
122
+ | Challenge is the core entity class storing action rules and reward configuration in funifier-service | ✓ verified | Class:src/main/java/com/funifier/engine/challenge/Challenge.java:Challenge |
123
+ | ChallengeManager manages challenge lifecycle including progress checking and achievement dispatch | ✓ verified | Class:src/main/java/com/funifier/engine/challenge/ChallengeManager.java:ChallengeManager |
@@ -96,3 +96,10 @@ POST /v3/competition/join { "competition": "<_id>", "player": "<player_id>" }
96
96
  POST /v3/competition/leader/aggregate?id=<_id>
97
97
  GET /v3/competition/<_id>/execute (manual execution only)
98
98
  ```
99
+
100
+ ## Verified References
101
+
102
+ | Claim | Status | Evidence |
103
+ |-------|--------|----------|
104
+ | Competition is the entity class for timed ranking contests with enrollment and position-based rewards in funifier-service | ✓ verified | Class:src/main/java/com/funifier/engine/competition/Competition.java:Competition |
105
+ | CompetitionManager manages competition execution, ranking computation, and reward distribution in funifier-service | ✓ verified | Class:src/main/java/com/funifier/engine/competition/CompetitionManager.java:CompetitionManager |
@@ -572,3 +572,9 @@ funifier_list type=crossword search=<titulo>
572
572
  ```
573
573
 
574
574
  Teste o jogo no Studio e verifique que as dicas e palavras estão corretas.
575
+
576
+ ## Verified References
577
+
578
+ | Claim | Status | Evidence |
579
+ |-------|--------|----------|
580
+ | Crossword is the entity class for word puzzle games with title, words, and clue positions in funifier-service | ✓ verified | Class:src/main/java/com/funifier/engine/crossword/Crossword.java:Crossword |
@@ -89,3 +89,9 @@ DELETE /v3/database/car__c?q=_id:'car001'
89
89
  ### 7. Usar em triggers
90
90
 
91
91
  Para executar trigger em eventos da coleção, use `entity: "car__c"` no payload do trigger.
92
+
93
+ ## Verified References
94
+
95
+ | Claim | Status | Evidence |
96
+ |-------|--------|----------|
97
+ | DatabaseManager provides MongoDB connection for custom __c collection CRUD operations in funifier-service | ✓ verified | Class:src/main/java/com/funifier/engine/database/DatabaseManager.java:DatabaseManager |