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.
- package/.cursor/rules/funifier.mdc +38 -41
- package/.github/copilot-instructions.md +38 -41
- package/AGENTS.md +56 -49
- package/README.md +40 -22
- package/datasource-funifier-docs/.coverage.json +326 -0
- package/datasource-funifier-docs/.validation.json +593 -0
- package/datasource-funifier-docs/knowledge/guides/aggregates.md +182 -70
- package/datasource-funifier-docs/knowledge/guides/database-access.md +174 -88
- package/datasource-funifier-docs/knowledge/guides/java-entities.md +294 -204
- package/datasource-funifier-docs/knowledge/guides/java-libraries.md +202 -226
- package/datasource-funifier-docs/knowledge/guides/java-managers.md +343 -265
- package/datasource-funifier-docs/knowledge/guides/trigger-examples.md +180 -236
- package/datasource-funifier-docs/knowledge/guides/triggers-guide.md +273 -191
- package/datasource-funifier-docs/knowledge/index.md +5 -2
- package/datasource-funifier-docs/knowledge/modules/achievement.md +1126 -28
- package/datasource-funifier-docs/knowledge/modules/action-log.md +469 -62
- package/datasource-funifier-docs/knowledge/modules/action.md +522 -70
- package/datasource-funifier-docs/knowledge/modules/auth.md +718 -69
- package/datasource-funifier-docs/knowledge/modules/avatar.md +483 -18
- package/datasource-funifier-docs/knowledge/modules/backup.md +603 -25
- package/datasource-funifier-docs/knowledge/modules/challenge.md +1048 -220
- package/datasource-funifier-docs/knowledge/modules/compact.md +469 -26
- package/datasource-funifier-docs/knowledge/modules/competition.md +811 -109
- package/datasource-funifier-docs/knowledge/modules/crossword.md +504 -28
- package/datasource-funifier-docs/knowledge/modules/csv-data.md +645 -20
- package/datasource-funifier-docs/knowledge/modules/custom-object.md +701 -36
- package/datasource-funifier-docs/knowledge/modules/database.md +730 -164
- package/datasource-funifier-docs/knowledge/modules/folder.md +1011 -77
- package/datasource-funifier-docs/knowledge/modules/kpi-formulas.md +410 -15
- package/datasource-funifier-docs/knowledge/modules/lastmile.md +568 -29
- package/datasource-funifier-docs/knowledge/modules/leaderboard.md +595 -126
- package/datasource-funifier-docs/knowledge/modules/level.md +536 -54
- package/datasource-funifier-docs/knowledge/modules/lottery.md +809 -76
- package/datasource-funifier-docs/knowledge/modules/marketplace.md +688 -17
- package/datasource-funifier-docs/knowledge/modules/mystery.md +662 -52
- package/datasource-funifier-docs/knowledge/modules/notification.md +564 -26
- package/datasource-funifier-docs/knowledge/modules/patterns.md +519 -814
- package/datasource-funifier-docs/knowledge/modules/player.md +773 -73
- package/datasource-funifier-docs/knowledge/modules/point.md +380 -83
- package/datasource-funifier-docs/knowledge/modules/public.md +508 -178
- package/datasource-funifier-docs/knowledge/modules/question.md +619 -99
- package/datasource-funifier-docs/knowledge/modules/quiz.md +565 -120
- package/datasource-funifier-docs/knowledge/modules/scheduler.md +1092 -39
- package/datasource-funifier-docs/knowledge/modules/security.md +674 -112
- package/datasource-funifier-docs/knowledge/modules/staging.md +742 -19
- package/datasource-funifier-docs/knowledge/modules/story.md +565 -29
- package/datasource-funifier-docs/knowledge/modules/studio-page.md +470 -144
- package/datasource-funifier-docs/knowledge/modules/swap.md +552 -84
- package/datasource-funifier-docs/knowledge/modules/team.md +563 -45
- package/datasource-funifier-docs/knowledge/modules/trigger.md +876 -134
- package/datasource-funifier-docs/knowledge/modules/upload.md +468 -95
- package/datasource-funifier-docs/knowledge/modules/virtual-good.md +510 -63
- package/datasource-funifier-docs/knowledge/modules/webhook.md +375 -28
- package/datasource-funifier-docs/knowledge/modules/websocket.md +459 -26
- package/datasource-funifier-docs/knowledge/modules/widget.md +613 -27
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +42 -1
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/init.test.js +74 -3
- package/dist/cli/init.test.js.map +1 -1
- package/dist/cli/persona.d.ts +3 -0
- package/dist/cli/persona.d.ts.map +1 -0
- package/dist/cli/persona.js +25 -0
- package/dist/cli/persona.js.map +1 -0
- package/dist/core/api-client.d.ts +21 -1
- package/dist/core/api-client.d.ts.map +1 -1
- package/dist/core/api-client.js +154 -1
- package/dist/core/api-client.js.map +1 -1
- package/dist/core/constants.d.ts +14 -0
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +14 -0
- package/dist/core/constants.js.map +1 -1
- package/dist/core/types/Folder.d.ts +16 -0
- package/dist/core/types/Folder.d.ts.map +1 -0
- package/dist/core/types/Folder.js +3 -0
- package/dist/core/types/Folder.js.map +1 -0
- package/dist/core/types/FolderContent.d.ts +10 -0
- package/dist/core/types/FolderContent.d.ts.map +1 -0
- package/dist/core/types/FolderContent.js +3 -0
- package/dist/core/types/FolderContent.js.map +1 -0
- package/dist/core/types/FolderContentType.d.ts +10 -0
- package/dist/core/types/FolderContentType.d.ts.map +1 -0
- package/dist/core/types/FolderContentType.js +3 -0
- package/dist/core/types/FolderContentType.js.map +1 -0
- package/dist/core/types/FolderLog.d.ts +11 -0
- package/dist/core/types/FolderLog.d.ts.map +1 -0
- package/dist/core/types/FolderLog.js +3 -0
- package/dist/core/types/FolderLog.js.map +1 -0
- package/dist/core/types/index.d.ts +4 -0
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/core/types/index.js +4 -0
- package/dist/core/types/index.js.map +1 -1
- package/dist/mcp/bundle.js +121 -87
- package/dist/mcp/check-update.d.ts +2 -0
- package/dist/mcp/check-update.d.ts.map +1 -0
- package/dist/mcp/check-update.js +44 -0
- package/dist/mcp/check-update.js.map +1 -0
- package/dist/mcp/index.js +5 -2
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/resources/documentation.d.ts +1 -1
- package/dist/mcp/resources/documentation.d.ts.map +1 -1
- package/dist/mcp/resources/documentation.js +39 -3
- package/dist/mcp/resources/documentation.js.map +1 -1
- package/dist/mcp/tools/_char-guard.js +1 -1
- package/dist/mcp/tools/_char-guard.js.map +1 -1
- package/dist/mcp/tools/_fetch-current.d.ts +1 -1
- package/dist/mcp/tools/_fetch-current.d.ts.map +1 -1
- package/dist/mcp/tools/_fetch-current.js +12 -0
- package/dist/mcp/tools/_fetch-current.js.map +1 -1
- package/dist/mcp/tools/connect.d.ts.map +1 -1
- package/dist/mcp/tools/connect.js +18 -8
- package/dist/mcp/tools/connect.js.map +1 -1
- package/dist/mcp/tools/database.d.ts.map +1 -1
- package/dist/mcp/tools/database.js +59 -47
- package/dist/mcp/tools/database.js.map +1 -1
- package/dist/mcp/tools/database.test.js +2 -2
- package/dist/mcp/tools/database.test.js.map +1 -1
- package/dist/mcp/tools/delete.d.ts.map +1 -1
- package/dist/mcp/tools/delete.js +33 -3
- package/dist/mcp/tools/delete.js.map +1 -1
- package/dist/mcp/tools/execute.d.ts.map +1 -1
- package/dist/mcp/tools/execute.js +20 -9
- package/dist/mcp/tools/execute.js.map +1 -1
- package/dist/mcp/tools/folder.d.ts +4 -0
- package/dist/mcp/tools/folder.d.ts.map +1 -0
- package/dist/mcp/tools/folder.js +68 -0
- package/dist/mcp/tools/folder.js.map +1 -0
- package/dist/mcp/tools/get.d.ts.map +1 -1
- package/dist/mcp/tools/get.js +16 -6
- package/dist/mcp/tools/get.js.map +1 -1
- package/dist/mcp/tools/index.d.ts +1 -1
- package/dist/mcp/tools/index.d.ts.map +1 -1
- package/dist/mcp/tools/index.js +5 -1
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/list.d.ts.map +1 -1
- package/dist/mcp/tools/list.js +38 -14
- package/dist/mcp/tools/list.js.map +1 -1
- package/dist/mcp/tools/logs.d.ts.map +1 -1
- package/dist/mcp/tools/logs.js +15 -5
- package/dist/mcp/tools/logs.js.map +1 -1
- package/dist/mcp/tools/save.d.ts.map +1 -1
- package/dist/mcp/tools/save.js +26 -4
- package/dist/mcp/tools/save.js.map +1 -1
- package/dist/mcp/tools/save.test.js +192 -1
- package/dist/mcp/tools/save.test.js.map +1 -1
- package/dist/mcp/tools/search-docs.d.ts +3 -0
- package/dist/mcp/tools/search-docs.d.ts.map +1 -0
- package/dist/mcp/tools/search-docs.js +102 -0
- package/dist/mcp/tools/search-docs.js.map +1 -0
- package/package.json +6 -2
- package/skills/acquire-funifier-knowledge/SKILL.md +132 -0
- package/skills/acquire-funifier-knowledge/assets/templates/CONCERNS.md +25 -0
- package/skills/acquire-funifier-knowledge/assets/templates/CUSTOM_ENDPOINTS.md +24 -0
- package/skills/acquire-funifier-knowledge/assets/templates/CUSTOM_PAGES.md +24 -0
- package/skills/acquire-funifier-knowledge/assets/templates/GAME_MECHANICS.md +35 -0
- package/skills/acquire-funifier-knowledge/assets/templates/INTEGRATIONS.md +35 -0
- package/skills/acquire-funifier-knowledge/assets/templates/LEADERBOARDS.md +24 -0
- package/skills/acquire-funifier-knowledge/assets/templates/OVERVIEW.md +47 -0
- package/skills/acquire-funifier-knowledge/assets/templates/PLAYER_MODEL.md +31 -0
- package/skills/acquire-funifier-knowledge/assets/templates/SCHEDULERS.md +25 -0
- package/skills/acquire-funifier-knowledge/assets/templates/TECHNIQUES_AND_PATTERNS.md +26 -0
- package/skills/acquire-funifier-knowledge/assets/templates/TRIGGERS.md +27 -0
- package/skills/acquire-funifier-knowledge/references/funifier-inventory-checklist.md +81 -0
- package/skills/acquire-funifier-knowledge/references/game-techniques-taxonomy.md +62 -0
- package/skills/acquire-funifier-knowledge/references/mcp-call-patterns.md +118 -0
- package/skills/funifier/SKILL.md +88 -0
- package/skills/funifier/references/configure-security.md +96 -0
- package/skills/{funifier-create-action/SKILL.md → funifier/references/create-action.md} +0 -33
- package/skills/funifier/references/create-aggregate.md +144 -0
- package/skills/funifier/references/create-challenge.md +116 -0
- package/skills/funifier/references/create-competition.md +98 -0
- package/skills/funifier/references/create-crossword.md +574 -0
- package/skills/funifier/references/create-custom-object.md +91 -0
- package/skills/funifier/references/create-custom-page.md +135 -0
- package/skills/funifier/references/create-folder.md +104 -0
- package/skills/funifier/references/create-lastmile.md +643 -0
- package/skills/{funifier-create-leaderboard/SKILL.md → funifier/references/create-leaderboard.md} +0 -33
- package/skills/funifier/references/create-level.md +94 -0
- package/skills/funifier/references/create-lottery.md +913 -0
- package/skills/funifier/references/create-mystery.md +769 -0
- package/skills/funifier/references/create-notification.md +75 -0
- package/skills/{funifier-create-point/SKILL.md → funifier/references/create-point.md} +0 -33
- package/skills/funifier/references/create-quiz.md +98 -0
- package/skills/funifier/references/create-scheduler.md +141 -0
- package/skills/funifier/references/create-story.md +636 -0
- package/skills/funifier/references/create-swap.md +95 -0
- package/skills/{funifier-create-trigger/SKILL.md → funifier/references/create-trigger.md} +0 -33
- package/skills/funifier/references/create-virtual-good.md +96 -0
- package/skills/funifier/references/create-webhook.md +72 -0
- package/skills/funifier/references/create-websocket.md +71 -0
- package/skills/funifier/references/create-widget.md +76 -0
- package/skills/funifier/references/debug.md +87 -0
- package/skills/funifier/references/help.md +81 -0
- package/skills/funifier/references/implement-frontend.md +106 -0
- package/skills/funifier/references/import-csv.md +75 -0
- package/skills/funifier/references/manage-player.md +82 -0
- package/skills/funifier/references/manage-team.md +76 -0
- package/skills/funifier/references/upload-file.md +91 -0
- package/datasource-funifier-docs/.search-index.json +0 -17318
- package/datasource-funifier-docs/.skills-map.json +0 -73
- package/skills/funifier-create-aggregate/SKILL.md +0 -127
- package/skills/funifier-create-challenge/SKILL.md +0 -88
- package/skills/funifier-create-custom-page/SKILL.md +0 -127
- package/skills/funifier-create-level/SKILL.md +0 -87
- package/skills/funifier-create-quiz/SKILL.md +0 -87
- package/skills/funifier-create-scheduler/SKILL.md +0 -127
- package/skills/funifier-create-virtual-good/SKILL.md +0 -87
- package/skills/funifier-debug/SKILL.md +0 -92
- package/skills/funifier-help/SKILL.md +0 -86
- package/skills/funifier-implement-frontend/SKILL.md +0 -90
- package/skills/funifier-index/SKILL.md +0 -58
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# funifier-configure-security
|
|
2
|
+
|
|
3
|
+
Configure Funifier security settings — roles, scopes, app tokens, and auth parameters; use when setting up access control, fixing missing database scope errors, or configuring token expiry; not for writing frontend login code (use funifier-implement-frontend)
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Before starting — find relevant docs
|
|
8
|
+
|
|
9
|
+
Run lexical search to load only what you need:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx funifier-mcp search "security role scope token auth app permission basic bearer access-control" --skill funifier-configure-security
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Read only files returned with score > 0.5 (this threshold is printed in the search output).
|
|
16
|
+
|
|
17
|
+
## Primary docs for this skill
|
|
18
|
+
|
|
19
|
+
If search returns insufficient results, read directly:
|
|
20
|
+
|
|
21
|
+
- `datasource-funifier-docs/knowledge/modules/security.md`
|
|
22
|
+
|
|
23
|
+
## Steps
|
|
24
|
+
|
|
25
|
+
### Regras críticas
|
|
26
|
+
|
|
27
|
+
- **`timeout: ""` (string vazia) causa NPE** no auth — omita o campo ou use `"7d"`, nunca string vazia
|
|
28
|
+
- **Scope `database` é palavra-chave obrigatória** para `/v3/database` — `write_all` sozinho não basta
|
|
29
|
+
- **PUT é upsert total** — sempre inclua roles E apps existentes, senão serão perdidos
|
|
30
|
+
- **Token Basic da gamificação (público):** `base64(API_KEY + ":")` (dois-pontos no final, sem secret)
|
|
31
|
+
- **Token Basic do app (server-side):** `base64(API_KEY + ":" + APP_SECRET)`
|
|
32
|
+
|
|
33
|
+
### Scopes importantes
|
|
34
|
+
|
|
35
|
+
| Scope | Descrição |
|
|
36
|
+
|---|---|
|
|
37
|
+
| `read_all` | Leitura em todas as coleções |
|
|
38
|
+
| `write_all` | Escrita em todos os endpoints |
|
|
39
|
+
| `delete_all` | Exclusão em todos os endpoints |
|
|
40
|
+
| `database` | **Obrigatório** para `/v3/database` (sem ele, escrita silencia sem erro) |
|
|
41
|
+
| `write_database_<coll>` | Escrita em coleção específica |
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Steps
|
|
46
|
+
|
|
47
|
+
### 1. Obter configuração atual de segurança
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
GET /v3/database/security/<API_KEY>?strict=true
|
|
51
|
+
Authorization: Bearer <studio_token>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. Ler a documentação do módulo
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
datasource-funifier-docs/knowledge/modules/security.md
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3. Definir roles e apps
|
|
61
|
+
|
|
62
|
+
Configuração padrão para projetos com frontend:
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"_id": "API_KEY",
|
|
66
|
+
"roles": [
|
|
67
|
+
{ "name": "public", "scope": "read_all" },
|
|
68
|
+
{ "name": "player", "scope": "read_all, write_all, delete_all, database", "timeout": "7d" }
|
|
69
|
+
],
|
|
70
|
+
"apps": [
|
|
71
|
+
{ "name": "Backend App", "app_secret": "<GUID>", "scope": "read_all, write_all, delete_all, database" }
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 4. Gerar GUID para app secret (se necessário)
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
GET /v3/util/guid/new
|
|
80
|
+
Authorization: Bearer <studio_token>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 5. Salvar via PUT (não POST)
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
PUT /v3/database/security <payload acima>
|
|
87
|
+
Authorization: Bearer <studio_token>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 6. Verificar
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
GET /v3/database/security/<API_KEY>?strict=true
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Teste login de jogador e confirme que o token retornado tem os scopes corretos.
|
|
@@ -1,32 +1,7 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: funifier-create-action
|
|
3
|
-
description: Create a Funifier action — define trackable player behaviors with attributes
|
|
4
|
-
---
|
|
5
|
-
|
|
6
1
|
# funifier-create-action
|
|
7
2
|
|
|
8
3
|
Create a Funifier action — define trackable player behaviors with attributes
|
|
9
4
|
|
|
10
|
-
## Persona e Qualidade de Código
|
|
11
|
-
|
|
12
|
-
A partir de agora, atue como um **desenvolvedor de software sênior altamente experiente**, especializado em **geração de código limpo, legível e de fácil manutenção**. Suas soluções devem seguir rigorosamente as **boas práticas da indústria**, **padrões de projeto** e **arquiteturas modernas**, sempre **evitando overengineering**.
|
|
13
|
-
|
|
14
|
-
### Ao lidar com qualquer código — seja refatorando ou criando do zero — siga este processo:
|
|
15
|
-
|
|
16
|
-
1. **Analise cuidadosamente o problema ou o código existente.**
|
|
17
|
-
2. **Raciocine passo a passo** antes de escrever qualquer linha de código.
|
|
18
|
-
3. **Identifique problemas (em caso de refatoração) ou requisitos (em caso de código novo).**
|
|
19
|
-
4. **Defina prioridades e estratégias com base em princípios sólidos de engenharia.**
|
|
20
|
-
5. **Justifique tecnicamente cada decisão**, com base em fundamentos como:
|
|
21
|
-
- **SOLID**
|
|
22
|
-
- **DRY (Don't Repeat Yourself)**
|
|
23
|
-
- **KISS (Keep It Simple, Stupid)**
|
|
24
|
-
- **YAGNI (You Aren't Gonna Need It)**
|
|
25
|
-
|
|
26
|
-
Só então prossiga com a implementação.
|
|
27
|
-
|
|
28
|
-
> **Nota:** Os exemplos de código na documentação Funifier são ilustrativos — podem usar nomes de variáveis genéricos ou scripts monolíticos. Sempre melhore-os: use nomes descritivos, extraia métodos especializados para lógicas complexas e mantenha cada função com responsabilidade única.
|
|
29
|
-
|
|
30
5
|
---
|
|
31
6
|
|
|
32
7
|
## Before starting — find relevant docs
|
|
@@ -116,11 +91,3 @@ funifier_list type=action search=<_id>
|
|
|
116
91
|
```
|
|
117
92
|
|
|
118
93
|
Do NOT use `funifier_logs` — that is only for triggers and schedulers.
|
|
119
|
-
|
|
120
|
-
## MCP
|
|
121
|
-
|
|
122
|
-
If Funifier MCP tools are available (`funifier_list`, `funifier_save`, `funifier_get`, `funifier_logs`):
|
|
123
|
-
- Use MCP for live server data
|
|
124
|
-
- Use docs for correct patterns and syntax
|
|
125
|
-
- Never learn patterns from existing live resources — docs are authoritative
|
|
126
|
-
- **For any new Funifier task, check `/funifier-index` first** — there may be a skill with the correct enums, examples, and workflow already defined
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# funifier-create-aggregate
|
|
2
|
+
|
|
3
|
+
Create a Funifier prepared aggregate — guided workflow for building MongoDB aggregate pipelines for reports and dashboards
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Formato do payload (obrigatório)
|
|
8
|
+
|
|
9
|
+
Funifier armazena código como **strings JSON escapadas**. Ao montar o payload do `funifier_save`:
|
|
10
|
+
|
|
11
|
+
- **Quebra de linha** → `\n` (nunca newline literal dentro da string)
|
|
12
|
+
- **Aspas duplas** dentro do código → `\"`
|
|
13
|
+
- **Backslash** → `\\` (regex `\b` vira `\\b`; dentro de Groovy com string-building pode exigir `\\\\b`)
|
|
14
|
+
- **Tab** → `\t` (se usar)
|
|
15
|
+
- **Pipelines de aggregate** vão como **string JSON** (não objeto aninhado) — serialize o array inteiro
|
|
16
|
+
|
|
17
|
+
A regra prática: monte o objeto em JavaScript normalmente e passe por `JSON.stringify` — o MCP faz isso automaticamente quando você entrega o payload como JSON. **Nunca** cole código multilinha cru no meio do JSON.
|
|
18
|
+
|
|
19
|
+
### Exemplo 1 — custom-page (html + angularjs script)
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"title": "Ciclos",
|
|
24
|
+
"slug": "studio/custom/ciclos",
|
|
25
|
+
"html": "<div class=\"row\">\n <div class=\"col-md-12\">\n <h2>Ciclos</h2>\n </div>\n</div>\n",
|
|
26
|
+
"script": "$scope.all = [];\n$scope.loading = false;\n\n$scope.list = function () {\n $scope.loading = true;\n};\n$scope.list();\n"
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Exemplo 2 — aggregate preparado (pipeline JSON + script Groovy)
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"_id": "extrato",
|
|
35
|
+
"title": "Extrato de Pontos",
|
|
36
|
+
"collection": "extrato",
|
|
37
|
+
"aggregate": "[\n {\n \"$match\": { \"player\": \"$param:player\" }\n },\n {\n \"$sort\": { \"time\": -1 }\n }\n]",
|
|
38
|
+
"script": "void prepare(aggregations, params) {\n if (context.get(\"player\") != null) {\n params.put(\"player\", context.get(\"player\"));\n } else {\n params.put(\"player\", \"NAO_EXISTE\");\n }\n}\n"
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Note que `aggregate` é uma **string** contendo JSON serializado (com `\n` e `\"` escapados), **não** um array nativo. Mesma regra vale para `script` em triggers/schedulers/aggregates e `html`/`script` em custom-pages.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Before starting — find relevant docs
|
|
47
|
+
|
|
48
|
+
Run lexical search to load only what you need:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npx funifier-mcp search "aggregate mongodb pipeline report dashboard query prepared" --skill funifier-create-aggregate
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Read only files returned with score > 0.5 (this threshold is printed in the search output).
|
|
55
|
+
|
|
56
|
+
## Primary docs for this skill
|
|
57
|
+
|
|
58
|
+
If search returns insufficient results, read directly:
|
|
59
|
+
|
|
60
|
+
- `datasource-funifier-docs/knowledge/guides/aggregates.md`
|
|
61
|
+
- `datasource-funifier-docs/knowledge/guides/database-access.md`
|
|
62
|
+
- `datasource-funifier-docs/knowledge/modules/database.md`
|
|
63
|
+
|
|
64
|
+
## Steps
|
|
65
|
+
|
|
66
|
+
### Coleções principais
|
|
67
|
+
|
|
68
|
+
| Coleção | Conteúdo chave |
|
|
69
|
+
|---|---|
|
|
70
|
+
| `achievement` | Conquistas — `type`: 0=Point, 1=Challenge, 2=VirtualGood, 3=Level |
|
|
71
|
+
| `action_log` | Ações executadas — `actionId`, `userId`, `attributes`, `time` |
|
|
72
|
+
| `player` | Jogadores — `_id`, `name`, `teams`, `extra` |
|
|
73
|
+
| `challenge` | Desafios — `_id`, `challenge`, `rules`, `points` |
|
|
74
|
+
| `point_category` | Tipos de ponto — `_id`, `category`, `shortName` |
|
|
75
|
+
| `catalog_item` | Loja virtual — `_id`, `catalogId`, `name`, `requires` |
|
|
76
|
+
|
|
77
|
+
### Expressões de data Funifier
|
|
78
|
+
|
|
79
|
+
| Expressão | Significado |
|
|
80
|
+
|---|---|
|
|
81
|
+
| `{"$date": "-0d-"}` | Início do dia atual |
|
|
82
|
+
| `{"$date": "-0M-"}` | Início do mês atual |
|
|
83
|
+
| `{"$date": "-0M+"}` | Fim do mês atual |
|
|
84
|
+
| `{"$date": "-0y-"}` | Início do ano atual |
|
|
85
|
+
| `{"$date": "-1d-"}` | Início do dia anterior |
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Steps
|
|
90
|
+
|
|
91
|
+
### 1. Identificar a necessidade
|
|
92
|
+
|
|
93
|
+
- Qual collection tem os dados? (ver tabela acima)
|
|
94
|
+
- Qual o filtro? (período, jogador, tipo de conquista)
|
|
95
|
+
- Qual o agrupamento? (por jogador, por dia, por equipe)
|
|
96
|
+
- Qual ordenação e limite?
|
|
97
|
+
|
|
98
|
+
### 2. Verificar se já existe
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
funifier_list type=aggregate search=<titulo>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 3. Construir e testar o pipeline
|
|
105
|
+
|
|
106
|
+
Top 10 jogadores com mais pontos no mês:
|
|
107
|
+
```json
|
|
108
|
+
[
|
|
109
|
+
{"$match": {"type": 0, "item": "xp", "time": {"$gte": {"$date": "-0M-"}, "$lte": {"$date": "-0M+"}}}},
|
|
110
|
+
{"$group": {"_id": "$player", "total": {"$sum": "$total"}}},
|
|
111
|
+
{"$sort": {"total": -1}},
|
|
112
|
+
{"$lookup": {"from": "player", "localField": "_id", "foreignField": "_id", "as": "p"}},
|
|
113
|
+
{"$unwind": "$p"},
|
|
114
|
+
{"$project": {"_id": 1, "player": "$p.name", "total": 1}},
|
|
115
|
+
{"$limit": 10}
|
|
116
|
+
]
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Testar diretamente antes de registrar:
|
|
120
|
+
```
|
|
121
|
+
POST /v3/database/achievement/aggregate
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 4. Registrar como Prepared Aggregate
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"_id": "top_players_month",
|
|
129
|
+
"title": "Top Players Month",
|
|
130
|
+
"collection": "achievement",
|
|
131
|
+
"aggregate": "[{\"\$match\":{\"type\":0,\"item\":\"xp\"}},{\"\$group\":{\"_id\":\"\$player\",\"total\":{\"\$sum\":\"\$total\"}}},{\"\$sort\":{\"total\":-1}},{\"\$limit\":10}]",
|
|
132
|
+
"script": ""
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
funifier_save type=aggregate payload=<json>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 5. Validar
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
funifier_list type=aggregate search=<titulo>
|
|
144
|
+
```
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# funifier-create-challenge
|
|
2
|
+
|
|
3
|
+
Create a Funifier challenge — missions with action rules and point rewards
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Before starting — find relevant docs
|
|
8
|
+
|
|
9
|
+
Run lexical search to load only what you need:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx funifier-mcp search "challenge mission reward rules action points gamification" --skill funifier-create-challenge
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Read only files returned with score > 0.5 (this threshold is printed in the search output).
|
|
16
|
+
|
|
17
|
+
## Primary docs for this skill
|
|
18
|
+
|
|
19
|
+
If search returns insufficient results, read directly:
|
|
20
|
+
|
|
21
|
+
- `datasource-funifier-docs/knowledge/modules/challenge.md`
|
|
22
|
+
- `datasource-funifier-docs/knowledge/modules/action.md`
|
|
23
|
+
- `datasource-funifier-docs/knowledge/modules/point.md`
|
|
24
|
+
|
|
25
|
+
## Steps
|
|
26
|
+
|
|
27
|
+
### Regras críticas
|
|
28
|
+
|
|
29
|
+
- **Dependências**: Actions e Points devem existir **antes** de criar o challenge
|
|
30
|
+
- `techniques` é **obrigatório** — use `["GT35"]` (Quest List) na maioria dos casos
|
|
31
|
+
- `range` é necessário quando há mais de uma rule
|
|
32
|
+
|
|
33
|
+
### Referência rápida
|
|
34
|
+
|
|
35
|
+
| Campo | Enum | Significado |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `range` | `0` | Complete All (todas as rules) |
|
|
38
|
+
| `range` | `1` | Complete Any (qualquer rule) |
|
|
39
|
+
| `range` | `2` | Complete All in Order |
|
|
40
|
+
| `rules[].operator` | `5` | >= (padrão — N ou mais vezes) |
|
|
41
|
+
| `rules[].operator` | `1` | = (exatamente N vezes) |
|
|
42
|
+
| `limitTimeScale` | `5` | Day | `6` = Week | `7` = Month |
|
|
43
|
+
| `limitPerType` | `0` | Player | `1` = Team | `2` = Global |
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Steps
|
|
48
|
+
|
|
49
|
+
### 1. Confirmar dependências
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
funifier_list type=action search=<actionId>
|
|
53
|
+
funifier_list type=point search=<category>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 2. Verificar se já existe
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
funifier_list type=challenge search=<nome>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 3. Construir o payload
|
|
63
|
+
|
|
64
|
+
Challenge simples:
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"challenge": "Watch Video",
|
|
68
|
+
"description": "Watch a video to earn 10 xp",
|
|
69
|
+
"techniques": ["GT35"],
|
|
70
|
+
"rules": [{ "actionId": "watch_video", "operator": 5, "total": 1 }],
|
|
71
|
+
"points": [{ "total": 10, "category": "xp", "operation": 0 }]
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Com filtro de atributo:
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"challenge": "Sell 10 Books",
|
|
79
|
+
"techniques": ["GT35"],
|
|
80
|
+
"rules": [{
|
|
81
|
+
"actionId": "sell",
|
|
82
|
+
"operator": 5,
|
|
83
|
+
"total": 10,
|
|
84
|
+
"filters": [{ "param": "product", "operator": 1, "value": "book" }]
|
|
85
|
+
}],
|
|
86
|
+
"points": [{ "total": 25, "category": "xp", "operation": 0 }]
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Com limite de frequência (1x por dia):
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"challenge": "Daily Check-in",
|
|
94
|
+
"techniques": ["GT35"],
|
|
95
|
+
"rules": [{ "actionId": "checkin", "operator": 5, "total": 1 }],
|
|
96
|
+
"points": [{ "total": 5, "category": "xp", "operation": 0 }],
|
|
97
|
+
"limitTotal": 1,
|
|
98
|
+
"limitPerType": 0,
|
|
99
|
+
"limitTimeAmount": 1,
|
|
100
|
+
"limitTimeScale": 5
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 4. Salvar
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
funifier_save type=challenge payload=<json>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 5. Validar
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
funifier_get type=challenge id=<_id>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Não use `funifier_logs` — isso é só para triggers e schedulers.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# funifier-create-competition
|
|
2
|
+
|
|
3
|
+
Create a Funifier competition — timed ranking contests with player enrollment, position-based rewards, and execution; use when you need player sign-up, prizes by finish position, or a scheduled end date, not when an always-on leaderboard is enough
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Before starting — find relevant docs
|
|
8
|
+
|
|
9
|
+
Run lexical search to load only what you need:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx funifier-mcp search "competition contest ranking tournament enrollment rewards position gt26" --skill funifier-create-competition
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Read only files returned with score > 0.5 (this threshold is printed in the search output).
|
|
16
|
+
|
|
17
|
+
## Primary docs for this skill
|
|
18
|
+
|
|
19
|
+
If search returns insufficient results, read directly:
|
|
20
|
+
|
|
21
|
+
- `datasource-funifier-docs/knowledge/modules/competition.md`
|
|
22
|
+
|
|
23
|
+
## Steps
|
|
24
|
+
|
|
25
|
+
### Rules — follow exactly, no exceptions
|
|
26
|
+
|
|
27
|
+
**Technique:** always `["GT26"]`.
|
|
28
|
+
**`operation.type`:**
|
|
29
|
+
- `1` = Count actions
|
|
30
|
+
- `3` = Sum achievements (points) — most common
|
|
31
|
+
|
|
32
|
+
**`period.expression`:** Funifier date syntax, e.g. `"-0M-;+1M+"` = current month.
|
|
33
|
+
**Rewards by position:** use `extra.position_start` and `extra.position_ends` on each reward.
|
|
34
|
+
**Execution:** automatic (`autoExecute: true`) or manual (`GET /v3/competition/:id/execute`).
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
### 1. Check dependencies
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
funifier_list type=point search=<metric>
|
|
42
|
+
funifier_list type=action search=<metric>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 2. Check if competition already exists
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
funifier_list type=competition search=<title>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 3. Build the payload
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"title": "Sales Race",
|
|
56
|
+
"description": "Top sellers of the month",
|
|
57
|
+
"period": { "expression": "-0M-;+1M+" },
|
|
58
|
+
"maxWinners": 3,
|
|
59
|
+
"maxPlayers": 100,
|
|
60
|
+
"minScore": 0,
|
|
61
|
+
"operation": {
|
|
62
|
+
"type": 3,
|
|
63
|
+
"achievement_type": 0,
|
|
64
|
+
"item": "xp",
|
|
65
|
+
"sort": -1,
|
|
66
|
+
"sub": false,
|
|
67
|
+
"filters": []
|
|
68
|
+
},
|
|
69
|
+
"rewards": [
|
|
70
|
+
{ "total": 200, "type": 0, "item": "xp", "operation": 0, "extra": { "position_start": 1, "position_ends": 1 }, "restrict": false, "perPlayer": false },
|
|
71
|
+
{ "total": 100, "type": 0, "item": "xp", "operation": 0, "extra": { "position_start": 2, "position_ends": 3 }, "restrict": false, "perPlayer": false }
|
|
72
|
+
],
|
|
73
|
+
"notifications": [],
|
|
74
|
+
"active": true,
|
|
75
|
+
"teamCompetition": false,
|
|
76
|
+
"autoExecute": true,
|
|
77
|
+
"techniques": ["GT26"]
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 4. Save
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
funifier_save type=competition payload=<json>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 5. Enroll players
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
POST /v3/competition/join { "competition": "<_id>", "player": "<player_id>" }
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 6. Check leaderboard and execute
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
POST /v3/competition/leader/aggregate?id=<_id>
|
|
97
|
+
GET /v3/competition/<_id>/execute (manual execution only)
|
|
98
|
+
```
|