funifier-mcp 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +182 -351
- package/datasource-funifier-docs/knowledge/guides/aggregates.md +152 -0
- package/datasource-funifier-docs/knowledge/guides/database-access.md +132 -0
- package/datasource-funifier-docs/knowledge/guides/java-entities.md +373 -0
- package/datasource-funifier-docs/knowledge/guides/java-libraries.md +330 -0
- package/datasource-funifier-docs/knowledge/guides/java-managers.md +509 -0
- package/datasource-funifier-docs/knowledge/guides/triggers-guide.md +271 -0
- package/datasource-funifier-docs/knowledge/index.md +121 -0
- package/datasource-funifier-docs/knowledge/modules/achievement.md +46 -0
- package/datasource-funifier-docs/knowledge/modules/action-log.md +88 -0
- package/datasource-funifier-docs/knowledge/modules/action.md +80 -0
- package/datasource-funifier-docs/knowledge/modules/auth.md +104 -0
- package/datasource-funifier-docs/knowledge/modules/avatar.md +28 -0
- package/datasource-funifier-docs/knowledge/modules/backup.md +40 -0
- package/datasource-funifier-docs/knowledge/modules/challenge.md +91 -0
- package/datasource-funifier-docs/knowledge/modules/compact.md +40 -0
- package/datasource-funifier-docs/knowledge/modules/competition.md +149 -0
- package/datasource-funifier-docs/knowledge/modules/crossword.md +41 -0
- package/datasource-funifier-docs/knowledge/modules/csv-data.md +30 -0
- package/datasource-funifier-docs/knowledge/modules/custom-object.md +53 -0
- package/datasource-funifier-docs/knowledge/modules/database.md +241 -0
- package/datasource-funifier-docs/knowledge/modules/folder.md +111 -0
- package/datasource-funifier-docs/knowledge/modules/kpi-formulas.md +23 -0
- package/datasource-funifier-docs/knowledge/modules/lastmile.md +45 -0
- package/datasource-funifier-docs/knowledge/modules/leaderboard.md +98 -0
- package/datasource-funifier-docs/knowledge/modules/level.md +83 -0
- package/datasource-funifier-docs/knowledge/modules/lottery.md +112 -0
- package/datasource-funifier-docs/knowledge/modules/marketplace.md +27 -0
- package/datasource-funifier-docs/knowledge/modules/mystery.md +82 -0
- package/datasource-funifier-docs/knowledge/modules/notification.md +40 -0
- package/datasource-funifier-docs/knowledge/modules/patterns.md +1096 -0
- package/datasource-funifier-docs/knowledge/modules/player.md +101 -0
- package/datasource-funifier-docs/knowledge/modules/point.md +67 -0
- package/datasource-funifier-docs/knowledge/modules/public.md +253 -0
- package/datasource-funifier-docs/knowledge/modules/question.md +136 -0
- package/datasource-funifier-docs/knowledge/modules/quiz.md +163 -0
- package/datasource-funifier-docs/knowledge/modules/scheduler.md +58 -0
- package/datasource-funifier-docs/knowledge/modules/security.md +169 -0
- package/datasource-funifier-docs/knowledge/modules/staging.md +28 -0
- package/datasource-funifier-docs/knowledge/modules/static-repo.md +41 -0
- package/datasource-funifier-docs/knowledge/modules/story.md +42 -0
- package/datasource-funifier-docs/knowledge/modules/studio-page.md +180 -0
- package/datasource-funifier-docs/knowledge/modules/swap.md +132 -0
- package/datasource-funifier-docs/knowledge/modules/team.md +75 -0
- package/datasource-funifier-docs/knowledge/modules/trigger.md +189 -0
- package/datasource-funifier-docs/knowledge/modules/upload.md +155 -0
- package/datasource-funifier-docs/knowledge/modules/virtual-good.md +99 -0
- package/datasource-funifier-docs/knowledge/modules/webhook.md +41 -0
- package/datasource-funifier-docs/knowledge/modules/websocket.md +41 -0
- package/datasource-funifier-docs/knowledge/modules/widget.md +42 -0
- package/datasource-funifier-docs/process-gtm-saas.md +143 -0
- package/datasource-funifier-docs/process-instagram.md +88 -0
- package/datasource-funifier-docs/process.md +1826 -0
- package/datasource-funifier-docs/readme.md +132 -0
- package/dist/cli/config-writers.d.ts +15 -0
- package/dist/cli/config-writers.d.ts.map +1 -0
- package/dist/cli/config-writers.js +55 -0
- package/dist/cli/config-writers.js.map +1 -0
- package/dist/cli/config-writers.test.d.ts +2 -0
- package/dist/cli/config-writers.test.d.ts.map +1 -0
- package/dist/cli/config-writers.test.js +55 -0
- package/dist/cli/config-writers.test.js.map +1 -0
- package/dist/cli/copy.d.ts +6 -0
- package/dist/cli/copy.d.ts.map +1 -0
- package/dist/cli/copy.js +63 -0
- package/dist/cli/copy.js.map +1 -0
- package/dist/cli/copy.test.d.ts +2 -0
- package/dist/cli/copy.test.d.ts.map +1 -0
- package/dist/cli/copy.test.js +94 -0
- package/dist/cli/copy.test.js.map +1 -0
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +167 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/paths.d.ts +7 -0
- package/dist/cli/paths.d.ts.map +1 -0
- package/dist/cli/paths.js +62 -0
- package/dist/cli/paths.js.map +1 -0
- package/dist/cli/paths.test.d.ts +2 -0
- package/dist/cli/paths.test.d.ts.map +1 -0
- package/dist/cli/paths.test.js +50 -0
- package/dist/cli/paths.test.js.map +1 -0
- package/dist/cli/platforms.d.ts +22 -0
- package/dist/cli/platforms.d.ts.map +1 -0
- package/dist/cli/platforms.js +50 -0
- package/dist/cli/platforms.js.map +1 -0
- package/dist/cli/prompts.d.ts +7 -0
- package/dist/cli/prompts.d.ts.map +1 -0
- package/dist/cli/prompts.js +49 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/bundle.js +94 -49
- package/dist/mcp/index.js +18 -1
- package/dist/mcp/index.js.map +1 -1
- package/package.json +4 -2
- package/skills/funifier-create-action/SKILL.md +86 -86
- package/skills/funifier-create-aggregate/SKILL.md +39 -0
- package/skills/funifier-create-challenge/SKILL.md +87 -87
- package/skills/funifier-create-custom-page/SKILL.md +39 -0
- package/skills/funifier-create-leaderboard/SKILL.md +87 -87
- package/skills/funifier-create-level/SKILL.md +86 -86
- package/skills/funifier-create-point/SKILL.md +86 -86
- package/skills/funifier-create-quiz/SKILL.md +86 -86
- package/skills/funifier-create-scheduler/SKILL.md +39 -0
- package/skills/funifier-create-trigger/SKILL.md +39 -0
- package/skills/funifier-create-virtual-good/SKILL.md +86 -86
- package/skills/funifier-debug/SKILL.md +90 -90
- package/skills/funifier-help/SKILL.md +85 -85
- package/skills/funifier-implement-frontend/SKILL.md +89 -89
- package/skills/funifier-index/SKILL.md +50 -50
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Swap (Troca)
|
|
2
|
+
|
|
3
|
+
**Acesso Studio:** `/studio/swap`
|
|
4
|
+
**API Endpoint:** `/v3/swap`
|
|
5
|
+
|
|
6
|
+
## O que é
|
|
7
|
+
|
|
8
|
+
Negociação e troca de objetos ou pontos entre jogadores. Permite que jogadores façam ofertas públicas de troca, negociando objetos ou pontos. Outros jogadores podem aceitar ou propor novas condições (contra propostas), incentivando a colaboração e interação.
|
|
9
|
+
|
|
10
|
+
## Quando usar
|
|
11
|
+
|
|
12
|
+
- Para criar mercados de troca (ex: figurinhas)
|
|
13
|
+
- Para permitir negociação entre jogadores
|
|
14
|
+
- Para incentivar interação social na gamificação
|
|
15
|
+
|
|
16
|
+
## Dependências
|
|
17
|
+
|
|
18
|
+
- **Virtual Good** e/ou **Point**: itens/pontos para troca devem existir
|
|
19
|
+
- **Player**: jogadores devem estar cadastrados
|
|
20
|
+
|
|
21
|
+
## Checklist de Configuração no Studio
|
|
22
|
+
|
|
23
|
+
- [ ] Verificar se jogadores possuem itens/pontos para troca
|
|
24
|
+
- [ ] Configurar interface de marketplace para os jogadores
|
|
25
|
+
|
|
26
|
+
## API Endpoints
|
|
27
|
+
|
|
28
|
+
### Listar Trocas
|
|
29
|
+
**Método:** GET
|
|
30
|
+
**Endpoint:** `/v3/database/swap`
|
|
31
|
+
|
|
32
|
+
### Criar Troca
|
|
33
|
+
**Método:** POST
|
|
34
|
+
**Endpoint:** `/v3/swap`
|
|
35
|
+
|
|
36
|
+
**Exemplo de Body:**
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"seller": "tom",
|
|
40
|
+
"rewards": [
|
|
41
|
+
{
|
|
42
|
+
"total": 1,
|
|
43
|
+
"type": 2,
|
|
44
|
+
"item": "DTj7lVn"
|
|
45
|
+
}
|
|
46
|
+
],
|
|
47
|
+
"requires": [
|
|
48
|
+
{
|
|
49
|
+
"total": 2,
|
|
50
|
+
"type": 0,
|
|
51
|
+
"item": "coin"
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Deletar Troca
|
|
58
|
+
**Método:** DELETE
|
|
59
|
+
**Endpoint:** `/v3/swap/:id`
|
|
60
|
+
|
|
61
|
+
### Realizar Troca (Adquirir)
|
|
62
|
+
**Método:** POST
|
|
63
|
+
**Endpoint:** `/v3/swap/acquire`
|
|
64
|
+
|
|
65
|
+
**Exemplo de Body:**
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"buyer": "jerry",
|
|
69
|
+
"swap": "650c67f88325771ffaa78a24"
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Receber Recompensas da Troca
|
|
74
|
+
**Método:** POST
|
|
75
|
+
**Endpoint:** `/v3/swap/receive`
|
|
76
|
+
|
|
77
|
+
**Exemplo de Body:**
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"swap": "650c67f88325771ffaa78a24"
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Listar Contra Propostas
|
|
85
|
+
**Método:** POST
|
|
86
|
+
**Endpoint:** `/v3/database/swap_counter_offer/aggregate`
|
|
87
|
+
|
|
88
|
+
### Criar Contra Proposta
|
|
89
|
+
**Método:** POST
|
|
90
|
+
**Endpoint:** `/v3/swap/counter/offer`
|
|
91
|
+
|
|
92
|
+
**Exemplo de Body:**
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"swap": "650c683c8325771ffaa78a3f",
|
|
96
|
+
"buyer": "jerry",
|
|
97
|
+
"offer": [
|
|
98
|
+
{
|
|
99
|
+
"total": 1,
|
|
100
|
+
"type": 0,
|
|
101
|
+
"item": "coin"
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Deletar Contra Proposta
|
|
108
|
+
**Método:** DELETE
|
|
109
|
+
**Endpoint:** `/v3/swap/counter/offer/:id`
|
|
110
|
+
|
|
111
|
+
### Aceitar Contra Proposta
|
|
112
|
+
**Método:** POST
|
|
113
|
+
**Endpoint:** `/v3/swap/counter/offer/accept`
|
|
114
|
+
|
|
115
|
+
**Exemplo de Body:**
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"offer": "650c69aa8325771ffaa78b1b"
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Receber Recompensas de Contra Proposta
|
|
123
|
+
**Método:** POST
|
|
124
|
+
**Endpoint:** `/v3/swap/counter/offer/receive`
|
|
125
|
+
|
|
126
|
+
## Validações e Testes
|
|
127
|
+
|
|
128
|
+
- [ ] Troca aparece na lista de swaps
|
|
129
|
+
- [ ] Comprador consegue adquirir a troca
|
|
130
|
+
- [ ] Vendedor recebe recompensas após troca
|
|
131
|
+
- [ ] Contra proposta é criada e listada corretamente
|
|
132
|
+
- [ ] Aceitar contra proposta funciona
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Team (Equipe)
|
|
2
|
+
|
|
3
|
+
**Acesso Studio:** `/studio/team`
|
|
4
|
+
**API Endpoint:** `/v3/team`
|
|
5
|
+
|
|
6
|
+
## O que é
|
|
7
|
+
|
|
8
|
+
Configuração de grupos ou equipes de jogadores. Permite criar grupos fixos (como "Equipe de Vendas") ou equipes dinâmicas, formadas automaticamente com base em critérios como aniversariantes do dia. Equipes permitem competição ou colaboração entre grupos.
|
|
9
|
+
|
|
10
|
+
## Quando usar
|
|
11
|
+
|
|
12
|
+
- Quando há competição ou colaboração entre grupos
|
|
13
|
+
- Para organizar jogadores por departamento, região ou função
|
|
14
|
+
- Para criar rankings por equipe
|
|
15
|
+
- Para atribuir desafios coletivos
|
|
16
|
+
|
|
17
|
+
## Checklist de Configuração no Studio
|
|
18
|
+
|
|
19
|
+
- [ ] Definir _id da equipe
|
|
20
|
+
- [ ] Definir nome da equipe
|
|
21
|
+
- [ ] Adicionar descrição e imagem/brasão (opcional)
|
|
22
|
+
- [ ] Adicionar membros à equipe
|
|
23
|
+
- [ ] Definir dono da equipe (owner)
|
|
24
|
+
|
|
25
|
+
## API Endpoints
|
|
26
|
+
|
|
27
|
+
### Listar Equipes
|
|
28
|
+
**Método:** GET
|
|
29
|
+
**Endpoint:** `/v3/team`
|
|
30
|
+
|
|
31
|
+
### Criar Equipe
|
|
32
|
+
**Método:** POST
|
|
33
|
+
**Endpoint:** `/v3/team`
|
|
34
|
+
|
|
35
|
+
**Exemplo de Body:**
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"_id": "sales",
|
|
39
|
+
"name": "Sales",
|
|
40
|
+
"description": "Funifier sales team",
|
|
41
|
+
"image": {
|
|
42
|
+
"small": {"url": "https://my.funifier.com/images/funny.png"},
|
|
43
|
+
"medium": {"url": "https://my.funifier.com/images/funny.png"},
|
|
44
|
+
"original": {"url": "https://my.funifier.com/images/funny.png"}
|
|
45
|
+
},
|
|
46
|
+
"extra": { "country": "USA" },
|
|
47
|
+
"owner": "john"
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Excluir Equipe
|
|
52
|
+
**Método:** DELETE
|
|
53
|
+
**Endpoint:** `/v3/team/:id`
|
|
54
|
+
|
|
55
|
+
### Adicionar Membro
|
|
56
|
+
**Método:** GET
|
|
57
|
+
**Endpoint:** `/v3/team/:id/member/add/:player`
|
|
58
|
+
|
|
59
|
+
### Remover Membro
|
|
60
|
+
**Método:** GET
|
|
61
|
+
**Endpoint:** `/v3/team/:team_id/member/remove/:player_id`
|
|
62
|
+
|
|
63
|
+
### Listar IDs dos Membros
|
|
64
|
+
**Método:** GET
|
|
65
|
+
**Endpoint:** `/v3/team/:team_id/memberids`
|
|
66
|
+
|
|
67
|
+
### Consultar Status da Equipe
|
|
68
|
+
**Método:** GET
|
|
69
|
+
**Endpoint:** `/v3/team/:id/status`
|
|
70
|
+
|
|
71
|
+
## Validações e Testes
|
|
72
|
+
|
|
73
|
+
- [ ] Equipe aparece na lista GET /v3/team
|
|
74
|
+
- [ ] Membros foram adicionados corretamente
|
|
75
|
+
- [ ] Status da equipe reflete pontos e desafios dos membros
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Trigger (Trigger)
|
|
2
|
+
|
|
3
|
+
**Acesso Studio:** `/studio/trigger`
|
|
4
|
+
**API Endpoint:** `/v3/trigger`
|
|
5
|
+
|
|
6
|
+
## O que é
|
|
7
|
+
|
|
8
|
+
Execução automática de códigos JAVA quando eventos específicos acontecem na gamificação. Permite programar ações customizadas disparadas por eventos, como o cadastro de um jogador ou a realização de uma compra. As triggers dão liberdade para alterar o comportamento padrão dos módulos, integrar com sistemas externos ou implementar automações em tempo real.
|
|
9
|
+
|
|
10
|
+
## Quando usar
|
|
11
|
+
|
|
12
|
+
- Para enviar emails automáticos (ex: boas-vindas)
|
|
13
|
+
- Para integrar com APIs externas (Zapier, CRM, etc.)
|
|
14
|
+
- Para alterar pontuação com regras especiais
|
|
15
|
+
- Para executar lógica de negócio personalizada
|
|
16
|
+
- **Importante:** usar apenas quando as configurações padrão não atendem
|
|
17
|
+
|
|
18
|
+
## Checklist de Configuração no Studio
|
|
19
|
+
|
|
20
|
+
- [ ] Definir nome e descrição da trigger
|
|
21
|
+
- [ ] Definir entidade observada (player, challenge, action, achievement, etc.)
|
|
22
|
+
- [ ] Definir evento (before_create, after_create, before_win, after_win, etc.)
|
|
23
|
+
- [ ] Escrever script Java com método `void trigger(event, entity, player, database)`
|
|
24
|
+
- [ ] Testar trigger em ambiente de homologação
|
|
25
|
+
|
|
26
|
+
## Eventos Disponíveis
|
|
27
|
+
|
|
28
|
+
| Prefixo | Sufixo | Descrição |
|
|
29
|
+
|---------|--------|-----------|
|
|
30
|
+
| before_ | create | Antes de criar |
|
|
31
|
+
| after_ | create | Depois de criar |
|
|
32
|
+
| before_ | update | Antes de atualizar |
|
|
33
|
+
| after_ | delete | Depois de deletar |
|
|
34
|
+
| before_ | win | Antes de conquistar |
|
|
35
|
+
| after_ | win | Depois de conquistar |
|
|
36
|
+
|
|
37
|
+
## Entidades Disponíveis
|
|
38
|
+
|
|
39
|
+
- `player`, `action`, `challenge`, `achievement`, `level`, `catalog_item`, `lottery`, `mystery_box`, `competition`, `question_log`, `<custom>__c`
|
|
40
|
+
|
|
41
|
+
## API Endpoints
|
|
42
|
+
|
|
43
|
+
### Listar Triggers
|
|
44
|
+
**Método:** GET
|
|
45
|
+
**Endpoint:** `/v3/trigger`
|
|
46
|
+
|
|
47
|
+
### Criar Trigger
|
|
48
|
+
**Método:** POST
|
|
49
|
+
**Endpoint:** `/v3/trigger`
|
|
50
|
+
|
|
51
|
+
**Exemplo de Body:**
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"name": "Make the player's name uppercase",
|
|
55
|
+
"_id": "DTv7uHc",
|
|
56
|
+
"description": "Before creating the player, change the letters of the name to uppercase",
|
|
57
|
+
"entity": "player",
|
|
58
|
+
"event": "before_create",
|
|
59
|
+
"script": "void trigger(event, entity, player, database){ entity.name = entity.name.toUpperCase(); }"
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Deletar Trigger
|
|
64
|
+
**Método:** DELETE
|
|
65
|
+
**Endpoint:** `/v3/trigger/:id`
|
|
66
|
+
|
|
67
|
+
## Script Runtime Environment (Wrapper Class)
|
|
68
|
+
|
|
69
|
+
O script da trigger **não é standalone** — ele é inserido dentro de uma classe Java wrapper gerada pelo Funifier, idêntica à do Public Endpoint (ver `public.md` para a lista completa de imports).
|
|
70
|
+
|
|
71
|
+
### Regras
|
|
72
|
+
|
|
73
|
+
1. **NÃO use `import`** — todos os imports já estão no wrapper (Unirest, Groovy JSON, Funifier entities/utils, Apache HTTP, Simple Java Mail, etc.)
|
|
74
|
+
2. Se precisar de uma classe não importada, use o nome completo: `com.example.MinhaClasse`
|
|
75
|
+
3. **`manager`** (ManagerFactory) está disponível como campo da classe
|
|
76
|
+
4. **Timeout padrão de 10 segundos** — pode ser customizado via campo `timeout` (em **segundos**) na API: `POST /v3/trigger` com `{"_id": "trigger_id", "timeout": 30}`. Este campo não aparece no Studio.
|
|
77
|
+
5. Scripts rodam em **Groovy** — cuidado com `$` em GStrings (usar `String.valueOf((char)0x24)` para operadores MongoDB)
|
|
78
|
+
6. Use apenas **ASCII em comentários** — UTF-8 especial pode causar parse errors
|
|
79
|
+
|
|
80
|
+
> 📖 Ver `public.md` → **Script Runtime Environment** para a lista completa de imports e bibliotecas disponíveis.
|
|
81
|
+
|
|
82
|
+
## Parâmetros do Script
|
|
83
|
+
|
|
84
|
+
- `event` (String): evento acionado
|
|
85
|
+
- `entity` (Object): objeto sendo manipulado (Player, ActionLog, Achievement, etc.)
|
|
86
|
+
- `player` (String): ID do jogador
|
|
87
|
+
- `database` (Object): utilitário para acessar o banco de dados
|
|
88
|
+
|
|
89
|
+
### ⚠️ CRITICAL: `entity` Type Depends on the Trigger Entity
|
|
90
|
+
|
|
91
|
+
O tipo do parâmetro `entity` varia conforme a entidade da trigger:
|
|
92
|
+
|
|
93
|
+
| Trigger Entity | Tipo de `entity` | Como acessar campos |
|
|
94
|
+
|---|---|---|
|
|
95
|
+
| `player` | `com.funifier.engine.player.Player` (objeto Java) | `entity.id`, `entity.name`, `entity.email`, `entity.extra` |
|
|
96
|
+
| `<custom>__c` | `java.util.Map` (documento MongoDB) | `entity.get("campo")`, `entity.put("campo", valor)` |
|
|
97
|
+
| `action` | `com.funifier.engine.action.ActionLog` | `entity.userId`, `entity.actionId`, `entity.attributes` |
|
|
98
|
+
| `achievement` | `com.funifier.engine.achievement.Achievement` | `entity.achievementId`, `entity.userId` |
|
|
99
|
+
|
|
100
|
+
**Erros comuns:**
|
|
101
|
+
- ❌ `entity.get("_id")` em trigger de `player` → `MissingMethodException: No signature of method: Player.get()`
|
|
102
|
+
- ✅ `entity.id` em trigger de `player`
|
|
103
|
+
- ❌ `entity.id` em trigger de `signup__c` → campo não existe no Map
|
|
104
|
+
- ✅ `entity.get("_id")` em trigger de `signup__c`
|
|
105
|
+
|
|
106
|
+
**Player fields (via `PlayerManager.java`):**
|
|
107
|
+
```
|
|
108
|
+
entity.id → String (_id do player)
|
|
109
|
+
entity.name → String
|
|
110
|
+
entity.email → String
|
|
111
|
+
entity.password → String (hash BCrypt)
|
|
112
|
+
entity.extra → Map<String, Object> (campos customizados)
|
|
113
|
+
entity.image → Image object
|
|
114
|
+
entity.business → boolean
|
|
115
|
+
entity.developer → boolean
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Fonte:** `PlayerManager.delete()` chama `TriggerRunner.run()` com `new Object[] { event, playerObject, playerId, gameDao }` — logo `entity` é o objeto `Player` completo, não um Map.
|
|
119
|
+
|
|
120
|
+
## Verificando Logs de Trigger (Studio)
|
|
121
|
+
|
|
122
|
+
Para ver se uma trigger executou com sucesso ou com erro:
|
|
123
|
+
|
|
124
|
+
1. Acessar **Studio** → menu lateral → **Triggers**
|
|
125
|
+
2. Na lista de triggers, cada uma tem um botão **🔥 Logs** na coluna OPERAÇÕES
|
|
126
|
+
3. Clicar em **Logs** abre um modal com:
|
|
127
|
+
- **Log Id**: identificador da trigger
|
|
128
|
+
- **Executou em**: data/hora da última execução
|
|
129
|
+
- **Tempo de resposta**: tempo de execução em ms
|
|
130
|
+
- **Erros**: se houve erro, mostra a exception completa em vermelho
|
|
131
|
+
4. Se não houver seção "Erros", a trigger executou com sucesso
|
|
132
|
+
|
|
133
|
+
**Dica:** Após alterar uma trigger via API (`POST /v3/trigger`), teste-a e verifique o log no Studio para confirmar que não há erros de compilação ou runtime.
|
|
134
|
+
|
|
135
|
+
## Utilitários Disponíveis no Contexto
|
|
136
|
+
|
|
137
|
+
| Classe/Método | Descrição |
|
|
138
|
+
|---|---|
|
|
139
|
+
| `Guid.newShortGuid()` | Gera um ID curto único (7 chars, ex: `FnwjKEY`) |
|
|
140
|
+
| `Guid.newGuid()` | Gera um GUID completo |
|
|
141
|
+
| `newShortGuid()` | ❌ **NÃO FUNCIONA** — precisa do prefixo `Guid.` |
|
|
142
|
+
| `com.funifier.engine.util.BCrypt.hashpw(pwd, BCrypt.gensalt())` | Hash de senha BCrypt |
|
|
143
|
+
| `new Date().getTime()` | Timestamp atual em milissegundos |
|
|
144
|
+
| `manager` | ManagerFactory — acesso a todos os managers |
|
|
145
|
+
|
|
146
|
+
> ⚠️ `System.currentTimeMillis()` é BLOQUEADO pelo SecureASTCustomizer. Usar `new Date().getTime()`.
|
|
147
|
+
|
|
148
|
+
## Managers Disponíveis
|
|
149
|
+
|
|
150
|
+
- `manager.getPlayerManager()` - findById, insert, delete
|
|
151
|
+
- `manager.getActionManager()` - findActionById, track, trackSynchronous
|
|
152
|
+
- `manager.getCatalogManager()` - findItemById, purchase, undoPurchase
|
|
153
|
+
- `manager.getLotteryManager()` - find, insertTicket, execute
|
|
154
|
+
- `manager.getAchievementManager()` - addAchievement
|
|
155
|
+
- `manager.getJongoConnection()` - acesso direto ao MongoDB
|
|
156
|
+
|
|
157
|
+
## Envio de Email
|
|
158
|
+
|
|
159
|
+
As triggers podem enviar emails usando o servidor SMTP configurado na gamificação. As classes do Simple Java Mail e utilitários Funifier já estão disponíveis no contexto (não precisa importar).
|
|
160
|
+
|
|
161
|
+
### Classes disponíveis
|
|
162
|
+
- `EmailBuilder` / `MailerBuilder` — Simple Java Mail (construir e enviar)
|
|
163
|
+
- `com.funifier.engine.mail.MailContext` — config SMTP da gamificação
|
|
164
|
+
- `com.funifier.controller.Configuration` — acesso à configuração atual
|
|
165
|
+
- `com.funifier.engine.util.MustacheUtils` — parse de templates com variáveis `{{campo}}`
|
|
166
|
+
|
|
167
|
+
### Exemplo básico
|
|
168
|
+
```java
|
|
169
|
+
Email email = EmailBuilder.startingBlank()
|
|
170
|
+
.from("App", "noreply@funifier.com")
|
|
171
|
+
.to(nome, emailDestinatario)
|
|
172
|
+
.withSubject("Assunto")
|
|
173
|
+
.withHTMLText("<h1>Olá</h1>")
|
|
174
|
+
.buildEmail();
|
|
175
|
+
|
|
176
|
+
com.funifier.engine.mail.MailContext ctx = com.funifier.controller.Configuration.getCurrentConfiguration().getMailContext();
|
|
177
|
+
MailerBuilder.withSMTPServer(ctx.hostName, ctx.smtpPort, ctx.authUser, ctx.authPassword)
|
|
178
|
+
.buildMailer()
|
|
179
|
+
.sendMail(email);
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
> 📖 Para o pattern completo com templates editáveis e Mustache, ver `patterns.md` → **Email Template Pattern**
|
|
183
|
+
|
|
184
|
+
## Validações e Testes
|
|
185
|
+
|
|
186
|
+
- [ ] Trigger aparece na lista GET /v3/trigger
|
|
187
|
+
- [ ] Evento é disparado corretamente
|
|
188
|
+
- [ ] Script executa sem erros
|
|
189
|
+
- [ ] Testar em staging antes de produção
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Upload (Upload)
|
|
2
|
+
|
|
3
|
+
**API Endpoint:** `/v3/upload`
|
|
4
|
+
|
|
5
|
+
## O que é
|
|
6
|
+
|
|
7
|
+
Upload de arquivos para uso na gamificação. Permite enviar imagens, documentos e outros tipos de arquivos para utilização em avatares, desafios, recursos visuais ou qualquer outra funcionalidade.
|
|
8
|
+
|
|
9
|
+
## Quando usar
|
|
10
|
+
|
|
11
|
+
- Para upload de imagens de avatares
|
|
12
|
+
- Para enviar documentos para treinamentos
|
|
13
|
+
- Para adicionar recursos visuais a desafios e itens
|
|
14
|
+
|
|
15
|
+
## API Endpoints
|
|
16
|
+
|
|
17
|
+
### Upload de Imagem
|
|
18
|
+
**Método:** POST
|
|
19
|
+
**Endpoint:** `/v3/upload/image`
|
|
20
|
+
**Content-Type:** multipart/form-data
|
|
21
|
+
|
|
22
|
+
**Campos do FormData:**
|
|
23
|
+
- `file`: conteúdo da imagem (ex: profile-pic.jpg)
|
|
24
|
+
- `extra`: `{ "session": "images" }`
|
|
25
|
+
|
|
26
|
+
**Headers:**
|
|
27
|
+
- `Authorization: {token}`
|
|
28
|
+
- `Content-Type: undefined` (gerenciado pelo FormData)
|
|
29
|
+
|
|
30
|
+
**⚠️ O campo `extra` é obrigatório.** Sem ele, a API retorna erro `Field extra is required`.
|
|
31
|
+
|
|
32
|
+
**Exemplo de Resposta:**
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"uploads": [
|
|
36
|
+
{
|
|
37
|
+
"bucket": "funifier/games/{apiKey}/images",
|
|
38
|
+
"extension": ".jpg",
|
|
39
|
+
"filename": "profile-pic.jpg",
|
|
40
|
+
"filename_unique": "{id}_original_profile-pic.jpg",
|
|
41
|
+
"size": 5559,
|
|
42
|
+
"content_type": "image/jpeg",
|
|
43
|
+
"thumb": "original",
|
|
44
|
+
"extra": { "session": "images" },
|
|
45
|
+
"_id": "6998ecbc434ba010175f4dd1",
|
|
46
|
+
"time": 1771629756465,
|
|
47
|
+
"url": "https://s3.amazonaws.com/funifier/games/{apiKey}/images/{id}_original_profile-pic.jpg"
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
"status": "OK"
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Exclusão de Arquivo por ID
|
|
55
|
+
**Método:** DELETE
|
|
56
|
+
**Endpoint:** `/v3/upload/{id}`
|
|
57
|
+
|
|
58
|
+
Remove o registro do banco de dados e exclui o arquivo físico do storage (S3/Azure/Google Cloud).
|
|
59
|
+
|
|
60
|
+
**Headers:**
|
|
61
|
+
- `Authorization: {token}`
|
|
62
|
+
|
|
63
|
+
**Resposta:** `204 No Content`
|
|
64
|
+
|
|
65
|
+
**Exemplo:**
|
|
66
|
+
```
|
|
67
|
+
DELETE /v3/upload/6998ecbc434ba010175f4dd1
|
|
68
|
+
Authorization: Bearer eyJhbGciOiJIUzUxMiIs...
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Observação:** A exclusão só é feita se o arquivo pertencer ao mesmo `apiKey` da autorização (verificado pela URL do arquivo).
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
### Exclusão de Arquivo por URL
|
|
76
|
+
**Método:** DELETE
|
|
77
|
+
**Endpoint:** `/v3/upload`
|
|
78
|
+
**Content-Type:** application/json
|
|
79
|
+
|
|
80
|
+
Remove o arquivo pelo campo `url`.
|
|
81
|
+
|
|
82
|
+
**Body:**
|
|
83
|
+
```json
|
|
84
|
+
{ "url": "https://s3.amazonaws.com/funifier/games/{apiKey}/images/{filename}" }
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Resposta:** `204 No Content`
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
### Uso com Player (Avatar)
|
|
93
|
+
|
|
94
|
+
Para usar a imagem como avatar do jogador, após o upload:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
POST /v3/player
|
|
98
|
+
{
|
|
99
|
+
"_id": "player_id",
|
|
100
|
+
"image": {
|
|
101
|
+
"small": { "url": "URL_DO_UPLOAD" },
|
|
102
|
+
"medium": { "url": "URL_DO_UPLOAD" },
|
|
103
|
+
"original": { "url": "URL_DO_UPLOAD" }
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Nota:** O campo `image` do player deve ter o formato `{ small: { url }, medium: { url }, original: { url } }`. A URL é obtida de `response.uploads[0].url`.
|
|
109
|
+
|
|
110
|
+
### Upload de Arquivo Genérico
|
|
111
|
+
**Método:** POST
|
|
112
|
+
**Endpoint:** `/v3/upload/file`
|
|
113
|
+
**Content-Type:** multipart/form-data
|
|
114
|
+
|
|
115
|
+
Suporta **qualquer tipo de arquivo** (não apenas imagens). Aceita múltiplos arquivos.
|
|
116
|
+
|
|
117
|
+
**Campos:**
|
|
118
|
+
- `file`: arquivo binário (pode repetir para vários)
|
|
119
|
+
- `extra`: string JSON obrigatória (ex: `{"session": "docs"}`)
|
|
120
|
+
|
|
121
|
+
**cURL:**
|
|
122
|
+
```bash
|
|
123
|
+
curl -X POST "{server}/v3/upload/file" \
|
|
124
|
+
-H "Authorization: Bearer {token}" \
|
|
125
|
+
-F 'file=@./documento.pdf;type=application/pdf' \
|
|
126
|
+
-F 'extra={"session":"docs","name":"manual"}'
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Deletar Upload por URL
|
|
130
|
+
**Método:** DELETE
|
|
131
|
+
**Endpoint:** `/v3/upload/image`
|
|
132
|
+
|
|
133
|
+
**Body:**
|
|
134
|
+
```json
|
|
135
|
+
{ "url": "https://s3.amazonaws.com/funifier/games/{APIKEY}/images/59359e..._logo.png" }
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Listar Uploads
|
|
139
|
+
**Método:** GET
|
|
140
|
+
**Endpoint:** `/v3/upload`
|
|
141
|
+
|
|
142
|
+
## Triggers de Upload
|
|
143
|
+
|
|
144
|
+
O upload dispara triggers `BEFORE_CREATE` e `AFTER_CREATE` na entidade `UPLOAD`. Isso permite:
|
|
145
|
+
- Validar arquivos antes de salvar
|
|
146
|
+
- Processar metadados após upload
|
|
147
|
+
- Integrar com outros módulos
|
|
148
|
+
|
|
149
|
+
## Validações e Testes
|
|
150
|
+
|
|
151
|
+
- [ ] Upload de imagem retorna URL válida
|
|
152
|
+
- [ ] Upload de arquivo genérico funciona
|
|
153
|
+
- [ ] URL da imagem é acessível publicamente
|
|
154
|
+
- [ ] Diferentes formatos são aceitos (jpg, png, pdf, etc.)
|
|
155
|
+
- [ ] Delete por URL remove o arquivo
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Virtual Good (Loja Virtual)
|
|
2
|
+
|
|
3
|
+
**Acesso Studio:** `/studio/catalog`
|
|
4
|
+
**API Endpoint:** `/v3/virtualgoods`
|
|
5
|
+
|
|
6
|
+
## O que é
|
|
7
|
+
|
|
8
|
+
Cadastro e gestão de objetos e benefícios que podem ser adquiridos pelos jogadores. Permite cadastrar produtos físicos, virtuais ou benefícios, estipular preços, quantidades, limites de compra e atributos. Os jogadores trocam pontos ou itens por objetos na loja.
|
|
9
|
+
|
|
10
|
+
## Quando usar
|
|
11
|
+
|
|
12
|
+
- Para criar sistema de recompensas tangíveis
|
|
13
|
+
- Para monetizar pontos/moedas virtuais
|
|
14
|
+
- Para dar senso de propriedade e escolha ao jogador
|
|
15
|
+
- Exemplos: camisetas, gift cards, itens virtuais, acessórios de avatar
|
|
16
|
+
|
|
17
|
+
## Dependências
|
|
18
|
+
|
|
19
|
+
- **Point**: moeda para compra deve existir
|
|
20
|
+
|
|
21
|
+
## Checklist de Configuração no Studio
|
|
22
|
+
|
|
23
|
+
- [ ] Criar catálogo (ex: "gifts", "rewards")
|
|
24
|
+
- [ ] Criar itens dentro do catálogo
|
|
25
|
+
- [ ] Definir preço (requires: tipo de ponto + quantidade)
|
|
26
|
+
- [ ] Definir quantidade em estoque (amount, -1 = ilimitado)
|
|
27
|
+
- [ ] Definir limite de compras por jogador
|
|
28
|
+
- [ ] Ativar item (active: true)
|
|
29
|
+
|
|
30
|
+
## API Endpoints
|
|
31
|
+
|
|
32
|
+
### Listar Catálogos
|
|
33
|
+
**Método:** GET
|
|
34
|
+
**Endpoint:** `/v3/virtualgoods/catalog`
|
|
35
|
+
|
|
36
|
+
### Criar Catálogo
|
|
37
|
+
**Método:** POST
|
|
38
|
+
**Endpoint:** `/v3/virtualgoods/catalog`
|
|
39
|
+
|
|
40
|
+
**Exemplo de Body:**
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"catalog": "Gifts",
|
|
44
|
+
"extra": {},
|
|
45
|
+
"i18n": {},
|
|
46
|
+
"_id": "gifts"
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Listar Itens
|
|
51
|
+
**Método:** GET
|
|
52
|
+
**Endpoint:** `/v3/virtualgoods/item`
|
|
53
|
+
|
|
54
|
+
### Criar Item
|
|
55
|
+
**Método:** POST
|
|
56
|
+
**Endpoint:** `/v3/virtualgoods/item`
|
|
57
|
+
|
|
58
|
+
**Exemplo de Body:**
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"catalogId": "gifts",
|
|
62
|
+
"name": "Bike",
|
|
63
|
+
"description": "Electric bike",
|
|
64
|
+
"amount": -1,
|
|
65
|
+
"active": true,
|
|
66
|
+
"extra": {},
|
|
67
|
+
"requires": [],
|
|
68
|
+
"rewards": [],
|
|
69
|
+
"notifications": [],
|
|
70
|
+
"i18n": {},
|
|
71
|
+
"techniques": ["GT08"],
|
|
72
|
+
"_id": "DTj7lVn"
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Realizar Compra
|
|
77
|
+
**Método:** POST
|
|
78
|
+
**Endpoint:** `/v3/virtualgoods/purchase`
|
|
79
|
+
|
|
80
|
+
**Exemplo de Body:**
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"player": "tom",
|
|
84
|
+
"item": "DTj7lVn",
|
|
85
|
+
"total": 1
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Excluir Compra
|
|
90
|
+
**Método:** DELETE
|
|
91
|
+
**Endpoint:** `/v3/virtualgoods/purchase`
|
|
92
|
+
|
|
93
|
+
## Validações e Testes
|
|
94
|
+
|
|
95
|
+
- [ ] Catálogo e itens aparecem nas respectivas listas
|
|
96
|
+
- [ ] Jogador consegue comprar item com saldo suficiente
|
|
97
|
+
- [ ] Compra debita pontos corretamente
|
|
98
|
+
- [ ] Estoque é decrementado (se não ilimitado)
|
|
99
|
+
- [ ] Limite de compras por jogador é respeitado
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# WebHook (WebHook)
|
|
2
|
+
|
|
3
|
+
**API Endpoint:** `/v3/webhook`
|
|
4
|
+
|
|
5
|
+
## O que é
|
|
6
|
+
|
|
7
|
+
Notificações automáticas para endpoints externos em tempo real. Permite que a Funifier envie notificações automáticas (payloads) para sistemas externos sempre que eventos importantes ocorrem na gamificação, sem necessidade de polling.
|
|
8
|
+
|
|
9
|
+
## Quando usar
|
|
10
|
+
|
|
11
|
+
- Para enviar dados para sistemas de BI quando um desafio é completado
|
|
12
|
+
- Para notificar CRM quando jogador atinge uma meta
|
|
13
|
+
- Para integrar com ferramentas externas (Slack, Teams, etc.)
|
|
14
|
+
- Para sincronizar dados em tempo real com outros sistemas
|
|
15
|
+
|
|
16
|
+
## Checklist de Configuração
|
|
17
|
+
|
|
18
|
+
- [ ] Definir URL do endpoint externo
|
|
19
|
+
- [ ] Definir eventos que disparam o webhook
|
|
20
|
+
- [ ] Definir formato do payload
|
|
21
|
+
- [ ] Testar conectividade com endpoint
|
|
22
|
+
|
|
23
|
+
## API Endpoints
|
|
24
|
+
|
|
25
|
+
### Listar Webhooks
|
|
26
|
+
**Método:** GET
|
|
27
|
+
**Endpoint:** `/v3/webhook`
|
|
28
|
+
|
|
29
|
+
### Criar Webhook
|
|
30
|
+
**Método:** POST
|
|
31
|
+
**Endpoint:** `/v3/webhook`
|
|
32
|
+
|
|
33
|
+
### Deletar Webhook
|
|
34
|
+
**Método:** DELETE
|
|
35
|
+
**Endpoint:** `/v3/webhook/:id`
|
|
36
|
+
|
|
37
|
+
## Validações e Testes
|
|
38
|
+
|
|
39
|
+
- [ ] Webhook aparece na lista
|
|
40
|
+
- [ ] Payload é enviado quando evento ocorre
|
|
41
|
+
- [ ] Endpoint externo recebe dados corretamente
|