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
|
@@ -1,96 +1,211 @@
|
|
|
1
1
|
# Aggregates Funifier
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 1. Visão Geral
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### 1.1 O que é este documento
|
|
6
6
|
|
|
7
|
-
**
|
|
8
|
-
**Endpoint:** `/v3/database/{collection}/aggregate`
|
|
9
|
-
**Body:** Pipeline JSON com comandos aggregate
|
|
7
|
+
Este documento descreve como executar pipelines de aggregate MongoDB na Funifier e a sintaxe das **expressões de data Funifier** — para relatórios, indicadores e rankings customizados. É o dono único das expressões de data.
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
### 1.2 Quando consultar
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
{"_id": "john", "name": "John Travolta", "email": "john@funifier.com", "teams": ["sales"], "extra": {"country": "USA", "department": "IT"}, "created": {"$date": "2023-07-05T20:57:25.776Z"}}
|
|
17
|
-
```
|
|
11
|
+
- Consulte ao construir **relatórios/dashboards** (top N, médias, contagens) via `$group`/`$sort`.
|
|
12
|
+
- Consulte ao precisar **juntar coleções** com `$lookup` (e por isso precisar das relações entre coleções).
|
|
13
|
+
- Consulte ao precisar de **filtros por data relativa** (`-0M-`, `-1d+`) em queries ou código.
|
|
18
14
|
|
|
19
|
-
###
|
|
20
|
-
Configurações dos tipos de ações.
|
|
21
|
-
```json
|
|
22
|
-
{"_id": "sell", "action": "Sell", "attributes": [{"name": "product", "type": "String"}, {"name": "price", "type": "Number"}], "active": true}
|
|
23
|
-
```
|
|
15
|
+
### 1.3 Quando NÃO consultar
|
|
24
16
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
{"_id": "64a5d92", "actionId": "sell", "userId": "john", "time": {"$date": "2023-07-05T20:57:33.303Z"}, "attributes": {"product": "book", "price": 120}}
|
|
29
|
-
```
|
|
17
|
+
- **NÃO** consulte para o **CRUD/mecânica geral** de `/v3/database` — use `datasource-funifier-docs/knowledge/guides/database-access.md`.
|
|
18
|
+
- **NÃO** consulte para os **métodos Java de `DateUtil`** (`fromKeyword`, `add`, escalas) — use `java-libraries.md` §4. Aqui fica a *semântica* das expressões.
|
|
19
|
+
- **NÃO** consulte para os **campos completos** das coleções — use `java-entities.md`. Aqui ficam só as relações relevantes a `$lookup`.
|
|
30
20
|
|
|
31
|
-
###
|
|
32
|
-
Conquistas dos jogadores. Campo `type`: 0=Point, 1=Challenge, 2=Virtual Good, 3=Level. Campo `player` → `player._id`.
|
|
33
|
-
```json
|
|
34
|
-
{"_id": "64a5d2", "player": "john", "total": 25.0, "type": 0, "item": "xp", "time": {"$date": "2023-07-05T20:57:33.303Z"}}
|
|
35
|
-
```
|
|
21
|
+
### 1.4 Índice de decisão
|
|
36
22
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
23
|
+
| Problema / Situação | O que fazer | Seção |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| Executar um pipeline | `POST /v3/database/:collection/aggregate` | §2 |
|
|
26
|
+
| Saber qual campo liga duas coleções (`$lookup`) | Ver relações entre coleções | §3 |
|
|
27
|
+
| Filtrar por "mês atual", "ontem", "este ano" | Expressões de data Funifier | §4 |
|
|
28
|
+
| Saber quais operadores são aceitos | Ver operadores suportados | §5 |
|
|
29
|
+
| Ver um pipeline pronto (top N, média, distintos) | Ver exemplos práticos | §6 |
|
|
42
30
|
|
|
43
|
-
###
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
31
|
+
### 1.5 Restrições globais críticas
|
|
32
|
+
|
|
33
|
+
> ⚠️ **O GET de listagem (`/v3/database`) não ordena.** Consequência de usar `_sort`: ignorado (`patterns.md` §1.5). → Para ordenar, use `$sort` num pipeline de aggregate.
|
|
34
|
+
|
|
35
|
+
> ⚠️ **Em escrita/leitura tipada, use `strict=true` (`?strict=true` na URL do aggregate).** Consequência de omitir: `Date` degrada para número e o `$match` por data falha (`patterns.md` §9).
|
|
36
|
+
|
|
37
|
+
> ⚠️ **`$` precisa de escape em código Groovy de Public Endpoint.** Consequência: operadores Mongo (`$match`, `$group`) quebram. → Ver o padrão de escape em `database-access.md` §3.
|
|
38
|
+
|
|
39
|
+
### 1.6 Documentos relacionados
|
|
40
|
+
|
|
41
|
+
> 📄 `datasource-funifier-docs/knowledge/guides/database-access.md` — mecânica de acesso e execução via API/Jongo
|
|
42
|
+
> 📄 `datasource-funifier-docs/knowledge/guides/java-libraries.md` §4 — métodos Java de `DateUtil`
|
|
43
|
+
> 📄 `datasource-funifier-docs/knowledge/guides/java-entities.md` — campos completos das coleções
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 2. Execução de Aggregate
|
|
48
|
+
|
|
49
|
+
Quando usar: rodar um pipeline de agregação sobre uma coleção.
|
|
50
|
+
Não usar quando: precisar só de um filtro simples → `GET ?q=` (`database-access.md` §2).
|
|
51
|
+
Depende de: token autenticado com `database` no scope.
|
|
52
|
+
Disponível em: API REST e código (Jongo).
|
|
53
|
+
|
|
54
|
+
### Descrição
|
|
55
|
+
|
|
56
|
+
Um aggregate aplica uma sequência de estágios (`$match`, `$group`, etc.) sobre os documentos de uma coleção e retorna o resultado transformado.
|
|
57
|
+
|
|
58
|
+
### Uso
|
|
59
|
+
|
|
60
|
+
**Via API REST:**
|
|
61
|
+
```
|
|
62
|
+
POST /v3/database/{collection}/aggregate?strict=true
|
|
63
|
+
[
|
|
64
|
+
{ "$match": { "player": "john", "type": 0, "item": "xp" } },
|
|
65
|
+
{ "$group": { "_id": null, "totalXP": { "$sum": "$total" } } }
|
|
66
|
+
]
|
|
67
|
+
→ [{ "totalXP": 250 }]
|
|
47
68
|
```
|
|
48
69
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
{
|
|
70
|
+
**Via Jongo (código):** cada estágio é um argumento de `.and(...)`:
|
|
71
|
+
```java
|
|
72
|
+
Iterable<Map> result = database.getCollection("achievement")
|
|
73
|
+
.aggregate("{$match: {type: 0, item: 'xp'}}")
|
|
74
|
+
.and("{$group: {_id: '$player', total: {$sum: '$total'}}}")
|
|
75
|
+
.and("{$sort: {total: -1}}")
|
|
76
|
+
.and("{$limit: 10}")
|
|
77
|
+
.as(Map.class);
|
|
53
78
|
```
|
|
54
79
|
|
|
55
|
-
|
|
80
|
+
### Armadilhas conhecidas
|
|
81
|
+
|
|
82
|
+
- **Esperar ordenação do GET** → não ordena (§1.5). Correção: `$sort` no pipeline.
|
|
83
|
+
- **Pipeline sem `strict=true` lendo datas** → `$match` por data falha (§1.5).
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 3. Coleções e Relações (para `$lookup`)
|
|
88
|
+
|
|
89
|
+
Quando usar: ao escrever `$lookup` e precisar saber qual campo liga as coleções.
|
|
90
|
+
Não usar quando: precisar de todos os campos da coleção → `java-entities.md`.
|
|
91
|
+
Depende de: `java-entities.md` (campos completos).
|
|
92
|
+
Disponível em: —
|
|
93
|
+
|
|
94
|
+
### Descrição
|
|
95
|
+
|
|
96
|
+
Relações que importam ao juntar coleções. Os exemplos mostram o documento mínimo; campos completos em `java-entities.md`.
|
|
56
97
|
|
|
57
|
-
|
|
98
|
+
### Uso
|
|
99
|
+
|
|
100
|
+
| Coleção | Relação-chave | Exemplo |
|
|
101
|
+
|---|---|---|
|
|
102
|
+
| `player` | `_id` é a ponta de `userId`/`player` | `{"_id":"john","name":"John","extra":{"department":"IT"}}` |
|
|
103
|
+
| `action_log` | `userId` → `player._id`; `actionId` → `action._id` | `{"actionId":"sell","userId":"john","attributes":{"price":120}}` |
|
|
104
|
+
| `achievement` | `player` → `player._id`; `item` → coleção do `type` | `{"player":"john","total":25.0,"type":0,"item":"xp"}` |
|
|
105
|
+
| `challenge` | `_id` é referenciado por `achievement.item` (type 1) | `{"_id":"DTo8dS3","challenge":"Watch Video"}` |
|
|
106
|
+
| `catalog_item` | `_id` é referenciado por `achievement.item` (type 2) | `{"_id":"prd1","name":"T-shirt"}` |
|
|
107
|
+
| `point_category` | `_id` é referenciado por `achievement.item` (type 0) | `{"_id":"xp","category":"Experience Points"}` |
|
|
108
|
+
|
|
109
|
+
> `achievement.type`: `0`=Point, `1`=Challenge, `2`=Virtual Good, `3`=Level, `5`=Lottery, `9`=Competition (`java-entities.md` §3). O `item` aponta para a coleção correspondente ao `type`.
|
|
110
|
+
|
|
111
|
+
### Armadilhas conhecidas
|
|
112
|
+
|
|
113
|
+
- **`$lookup` com `localField` errado** → resultado vazio. Correção: conferir a relação acima (ex: em `achievement`, juntar por `player` e não `_id`).
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 4. Expressões de Data Funifier
|
|
118
|
+
|
|
119
|
+
Quando usar: filtrar por períodos relativos ("mês atual", "ontem") em `$match` ou em código.
|
|
120
|
+
Não usar quando: a data é absoluta e conhecida → use ISO-8601 (`{"$date": "2023-08-01T00:00:00.000Z"}`).
|
|
121
|
+
Depende de: —
|
|
122
|
+
Disponível em: filtros de aggregate (`{"$date": "..."}`) e `DateUtil.fromKeyword(...)` (`java-libraries.md` §4).
|
|
123
|
+
|
|
124
|
+
### Descrição
|
|
125
|
+
|
|
126
|
+
Sintaxe própria da Funifier para datas relativas, resolvida no servidor. Formato: `[sinal][quantidade][unidade][ajuste]`.
|
|
127
|
+
|
|
128
|
+
- **Unidades:** `y`=ano, `M`=mês, `w`=semana, `d`=dia, `h`=hora, `m`=minuto, `s`=segundo
|
|
129
|
+
- **Ajuste:** `-` = início da unidade (floor), `+` = fim da unidade (ceil), sem ajuste = instante exato
|
|
130
|
+
|
|
131
|
+
### Uso
|
|
58
132
|
|
|
59
133
|
| Expressão | Significado |
|
|
60
134
|
|-----------|------------|
|
|
61
135
|
| `-0d` | Agora |
|
|
62
136
|
| `-0d-` | Início do dia atual (00:00:00) |
|
|
63
137
|
| `-0d+` | Fim do dia atual (23:59:59) |
|
|
64
|
-
| `-1d` | Exatamente
|
|
65
|
-
| `-1d-` | Início do dia anterior
|
|
66
|
-
| `-1d+` | Fim do dia anterior
|
|
138
|
+
| `-1d` | Exatamente 1 dia atrás |
|
|
139
|
+
| `-1d-` | Início do dia anterior |
|
|
140
|
+
| `-1d+` | Fim do dia anterior |
|
|
141
|
+
| `+1d` | Exatamente 1 dia no futuro |
|
|
142
|
+
| `+1d-` | Início do dia seguinte |
|
|
67
143
|
| `-0w-` | Início da semana atual |
|
|
68
144
|
| `-0w+` | Fim da semana atual |
|
|
69
|
-
| `-1w` | Exatamente
|
|
70
|
-
| `-0M-` |
|
|
71
|
-
| `-0M+` |
|
|
72
|
-
| `-1M` | Exatamente
|
|
73
|
-
| `-1M-` |
|
|
74
|
-
| `-0y-` |
|
|
75
|
-
| `-0y+` |
|
|
145
|
+
| `-1w` | Exatamente 1 semana atrás |
|
|
146
|
+
| `-0M-` | Primeiro dia do mês (00:00:00) |
|
|
147
|
+
| `-0M+` | Último dia do mês (23:59:59) |
|
|
148
|
+
| `-1M` | Exatamente 1 mês atrás |
|
|
149
|
+
| `-1M-` | Primeiro dia do mês anterior |
|
|
150
|
+
| `-0y-` | 1 de janeiro do ano atual |
|
|
151
|
+
| `-0y+` | 31 de dezembro do ano atual |
|
|
76
152
|
|
|
77
|
-
**
|
|
153
|
+
**Encadeamento com `|`** (ajustes e fuso):
|
|
154
|
+
```
|
|
155
|
+
-1d+|GMT+3 → fim do dia anterior no fuso GMT+3
|
|
156
|
+
-0d-|+5h|+30m|GMT-3 → início do dia + 5h30m no fuso GMT-3
|
|
157
|
+
```
|
|
78
158
|
|
|
79
|
-
**
|
|
159
|
+
**Em filtro de aggregate:**
|
|
80
160
|
```json
|
|
81
|
-
{"$date": "-0M-"}
|
|
161
|
+
{ "$match": { "time": { "$gte": { "$date": "-0M-" }, "$lte": { "$date": "-0M+" } } } }
|
|
82
162
|
```
|
|
83
163
|
|
|
84
|
-
|
|
164
|
+
**Em código:** `DateUtil.fromKeyword("-0M-")` (`java-libraries.md` §4).
|
|
165
|
+
|
|
166
|
+
### Armadilhas conhecidas
|
|
167
|
+
|
|
168
|
+
- **Esquecer o ajuste** (`-0M` em vez de `-0M-`) → instante exato, não início do mês. Correção: incluir `-`/`+` conforme o limite desejado.
|
|
169
|
+
- **`$gte` sem `$lte`** → janela aberta inclui o futuro. Correção: par `-0M-`/`-0M+`.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 5. Operadores Suportados
|
|
174
|
+
|
|
175
|
+
Quando usar: ao montar o pipeline.
|
|
176
|
+
Não usar quando: —
|
|
177
|
+
Depende de: —
|
|
178
|
+
Disponível em: API REST e Jongo.
|
|
179
|
+
|
|
180
|
+
### Descrição
|
|
181
|
+
|
|
182
|
+
Operadores de pipeline aceitos.
|
|
183
|
+
|
|
184
|
+
### Uso
|
|
85
185
|
|
|
86
186
|
`$match`, `$group`, `$sort`, `$limit`, `$lookup`, `$project`, `$unwind`, `$addFields`, `$count`
|
|
87
187
|
|
|
88
|
-
|
|
188
|
+
### Armadilhas conhecidas
|
|
189
|
+
|
|
190
|
+
- **Usar operador fora desta lista** → pode não ser suportado. Valide em homologação antes.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## 6. Exemplos Práticos
|
|
195
|
+
|
|
196
|
+
Quando usar: como ponto de partida para relatórios comuns.
|
|
197
|
+
Não usar quando: a necessidade é um CRUD simples → `database-access.md`.
|
|
198
|
+
Depende de: §3 (relações) e §4 (datas).
|
|
199
|
+
Disponível em: API REST.
|
|
89
200
|
|
|
90
|
-
###
|
|
201
|
+
### Descrição
|
|
91
202
|
|
|
203
|
+
Pipelines prontos para os relatórios mais frequentes.
|
|
204
|
+
|
|
205
|
+
### Uso
|
|
206
|
+
|
|
207
|
+
**Top 10 jogadores com mais XP no mês atual** (`POST /v3/database/achievement/aggregate`):
|
|
92
208
|
```json
|
|
93
|
-
// POST /v3/database/achievement/aggregate
|
|
94
209
|
[
|
|
95
210
|
{"$match": {"type": 0, "item": "xp", "time": {"$gte": {"$date": "-0M-"}, "$lte": {"$date": "-0M+"}}}},
|
|
96
211
|
{"$group": {"_id": "$player", "total": {"$sum": "$total"}}},
|
|
@@ -102,10 +217,8 @@ Formato: `[sinal][quantidade][unidade][ajuste opcional]`
|
|
|
102
217
|
]
|
|
103
218
|
```
|
|
104
219
|
|
|
105
|
-
|
|
106
|
-
|
|
220
|
+
**Jogadores distintos que completaram um desafio:**
|
|
107
221
|
```json
|
|
108
|
-
// POST /v3/database/achievement/aggregate
|
|
109
222
|
[
|
|
110
223
|
{"$match": {"type": 1, "item": "DTo8dS3"}},
|
|
111
224
|
{"$group": {"_id": "$player", "challenge": {"$first": "$item"}}},
|
|
@@ -115,20 +228,16 @@ Formato: `[sinal][quantidade][unidade][ajuste opcional]`
|
|
|
115
228
|
]
|
|
116
229
|
```
|
|
117
230
|
|
|
118
|
-
|
|
119
|
-
|
|
231
|
+
**Média de XP por jogador em mês específico:**
|
|
120
232
|
```json
|
|
121
|
-
// POST /v3/database/achievement/aggregate
|
|
122
233
|
[
|
|
123
234
|
{"$match": {"type": 0, "item": "xp", "time": {"$gte": {"$date": "2023-08-01T00:00:00.000Z"}, "$lte": {"$date": "2023-08-31T23:59:59.999Z"}}}},
|
|
124
235
|
{"$group": {"_id": "$player", "averageXP": {"$avg": "$total"}}}
|
|
125
236
|
]
|
|
126
237
|
```
|
|
127
238
|
|
|
128
|
-
|
|
129
|
-
|
|
239
|
+
**Top 3 itens mais vendidos este ano:**
|
|
130
240
|
```json
|
|
131
|
-
// POST /v3/database/achievement/aggregate
|
|
132
241
|
[
|
|
133
242
|
{"$match": {"type": 2, "time": {"$gte": {"$date": "-0y-"}, "$lte": {"$date": "-0y+"}}}},
|
|
134
243
|
{"$group": {"_id": "$item", "totalSold": {"$sum": "$total"}}},
|
|
@@ -139,10 +248,8 @@ Formato: `[sinal][quantidade][unidade][ajuste opcional]`
|
|
|
139
248
|
]
|
|
140
249
|
```
|
|
141
250
|
|
|
142
|
-
|
|
143
|
-
|
|
251
|
+
**Jogadores que executaram ações ontem** (`POST /v3/database/action_log/aggregate`):
|
|
144
252
|
```json
|
|
145
|
-
// POST /v3/database/action_log/aggregate
|
|
146
253
|
[
|
|
147
254
|
{"$match": {"time": {"$gte": {"$date": "-1d-"}, "$lte": {"$date": "-1d+"}}}},
|
|
148
255
|
{"$group": {"_id": "$userId"}},
|
|
@@ -150,3 +257,8 @@ Formato: `[sinal][quantidade][unidade][ajuste opcional]`
|
|
|
150
257
|
{"$project": {"_id": 1, "playerName": {"$first": "$p.name"}}}
|
|
151
258
|
]
|
|
152
259
|
```
|
|
260
|
+
|
|
261
|
+
### Armadilhas conhecidas
|
|
262
|
+
|
|
263
|
+
- **`$lookup` em `achievement` por `_id`** → resultado vazio; junte por `$player`/`$item` conforme o caso (§3).
|
|
264
|
+
- **`$project` esperando `$p.name` sem `$unwind`** → `$p` é array. Correção: `$unwind` ou `{"$first": "$p.name"}`.
|
|
@@ -1,132 +1,218 @@
|
|
|
1
1
|
# Acesso ao Banco de Dados Funifier
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 1. Visão Geral
|
|
4
4
|
|
|
5
|
-
1.
|
|
6
|
-
2. **Via código Java** — objeto `manager` em triggers, schedulers e public endpoints
|
|
5
|
+
### 1.1 O que é este documento
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
Este documento descreve as duas formas de acessar o MongoDB da Funifier — via API REST (`/v3/database`) e via código Java/Groovy (Jongo) — para operações CRUD, filtros e índices. É o dono único da mecânica de acesso ao banco.
|
|
8
|
+
|
|
9
|
+
### 1.2 Quando consultar
|
|
10
|
+
|
|
11
|
+
- Consulte ao **ler/escrever coleções** via API REST ou código.
|
|
12
|
+
- Consulte ao precisar dos **placeholders seguros** (`#`) do Jongo.
|
|
13
|
+
- Consulte ao **filtrar** uma listagem (`q`) ou gerir **índices**.
|
|
14
|
+
- Consulte ao escolher entre **`database.getCollection(...)`** (trigger) e **`manager.getJongoConnection()`** (scheduler/endpoint).
|
|
15
|
+
|
|
16
|
+
### 1.3 Quando NÃO consultar
|
|
17
|
+
|
|
18
|
+
- **NÃO** consulte para **pipelines de aggregate** (`$match`/`$group`/`$sort`) nem **expressões de data** — use `datasource-funifier-docs/knowledge/guides/aggregates.md`. Aqui fica só o endpoint/mecânica.
|
|
19
|
+
- **NÃO** consulte para escrita de **entidades nativas** (`player`, `action`, etc.) — use o endpoint nativo (`patterns.md` §10); `/v3/database` é para coleções genéricas/`__c`.
|
|
20
|
+
- **NÃO** consulte para **tipos BSON e strict mode em detalhe** — use `patterns.md` §9.
|
|
21
|
+
|
|
22
|
+
### 1.4 Índice de decisão
|
|
23
|
+
|
|
24
|
+
| Problema / Situação | O que fazer | Seção |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| Listar coleções existentes | `GET /v3/database/collections` | §2 |
|
|
27
|
+
| CRUD numa coleção genérica/`__c` | `/v3/database/:collection` | §2 |
|
|
28
|
+
| Filtrar uma listagem | `?q=campo:"valor"` (não `_filter`) | §2 |
|
|
29
|
+
| Ordenar resultados | `POST .../aggregate` com `$sort` (o GET não ordena) | §2 → `aggregates.md` |
|
|
30
|
+
| Ler/escrever em código (trigger) | `database.getCollection(...)` | §3 |
|
|
31
|
+
| Ler/escrever em código (scheduler/endpoint) | `manager.getJongoConnection()...` | §3 |
|
|
32
|
+
| Evitar injeção em query | placeholder `#` | §4 |
|
|
33
|
+
| Criar/listar/excluir índice | `/v3/database/:collection/index` | §5 |
|
|
34
|
+
|
|
35
|
+
### 1.5 Restrições globais críticas
|
|
36
|
+
|
|
37
|
+
> ⚠️ **O parâmetro de filtro é `q` (sintaxe Mongo), não `_filter`.** Consequência: `_filter`/`_sort`/`_limit` são **silenciosamente ignorados** e a query retorna todos os registros (`patterns.md` §1.5, `modules/database.md` §4.2). → Use `?q=campo:"valor"&strict=true`. Para ordenar, use `POST .../aggregate` com `$sort`.
|
|
38
|
+
|
|
39
|
+
> ⚠️ **`PUT /v3/database/:collection` é replace total.** Consequência: campos não enviados são apagados. → Envie o objeto completo (read-merge-write).
|
|
40
|
+
|
|
41
|
+
> ⚠️ **`POST /v3/database/:collection` (sem `/aggregate`) cria um documento.** Consequência de enviar um filtro esperando busca: cria lixo na coleção (`patterns.md` §10). → Para filtrar, use `GET ?q=`; para pipeline, `POST .../aggregate`.
|
|
42
|
+
|
|
43
|
+
> ⚠️ **Nunca use `/v3/database/player`.** `player` é entidade nativa; `GET` dá 404 e `PUT` faz replace perdendo campos (`patterns.md` §10). → Use `/v3/player`.
|
|
44
|
+
|
|
45
|
+
> ⚠️ **Use `strict=true` em todo GET/escrita de campos tipados.** Consequência de omitir: `Date` é lido como número e regravado com tipo errado, quebrando queries por data (`patterns.md` §9).
|
|
46
|
+
|
|
47
|
+
### 1.6 Documentos relacionados
|
|
48
|
+
|
|
49
|
+
> 📄 `datasource-funifier-docs/knowledge/guides/aggregates.md` — pipelines de aggregate e expressões de data
|
|
50
|
+
> 📄 `datasource-funifier-docs/knowledge/guides/java-libraries.md` §Jongo — ponteiro para este documento
|
|
51
|
+
> 📄 `datasource-funifier-docs/knowledge/modules/patterns.md` §9–§10 — strict mode, `q` vs `_filter`, Player nativo
|
|
9
52
|
|
|
10
53
|
---
|
|
11
54
|
|
|
12
|
-
##
|
|
55
|
+
## 2. Acesso via API REST (`/v3/database`)
|
|
56
|
+
|
|
57
|
+
Quando usar: ler/escrever coleções genéricas ou `__c` a partir do frontend ou de integrações.
|
|
58
|
+
Não usar quando: a coleção é uma entidade nativa (use o endpoint nativo) ou precisa de pipeline (use aggregate).
|
|
59
|
+
Depende de: token de autenticação com `database` no scope (`modules/security.md`).
|
|
60
|
+
Disponível em: API REST (cliente HTTP autenticado).
|
|
13
61
|
|
|
14
|
-
###
|
|
62
|
+
### Descrição
|
|
15
63
|
|
|
16
|
-
**
|
|
17
|
-
**Endpoint:** `/v3/database/collections`
|
|
64
|
+
CRUD genérico sobre qualquer coleção via REST. Todas as operações usam **MongoDB** por trás.
|
|
18
65
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
66
|
+
### Uso
|
|
67
|
+
|
|
68
|
+
**Listar coleções**
|
|
69
|
+
```
|
|
70
|
+
GET /v3/database/collections
|
|
71
|
+
→ ["player", "action_log", "achievement", "car__c", "email__c"]
|
|
22
72
|
```
|
|
23
73
|
|
|
24
|
-
|
|
74
|
+
**CRUD**
|
|
25
75
|
|
|
26
|
-
| Operação | Método | Endpoint |
|
|
27
|
-
|
|
28
|
-
| Create | POST | `/v3/database/:collection` |
|
|
29
|
-
| Read | GET | `/v3/database/:collection` |
|
|
30
|
-
| Update | PUT | `/v3/database/:collection`
|
|
31
|
-
| Delete | DELETE | `/v3/database/:collection?q=...` |
|
|
32
|
-
| Bulk
|
|
76
|
+
| Operação | Método | Endpoint |
|
|
77
|
+
|----------|--------|----------|
|
|
78
|
+
| Create | POST | `/v3/database/:collection` |
|
|
79
|
+
| Read (lista) | GET | `/v3/database/:collection?q=...&strict=true` |
|
|
80
|
+
| Update | PUT | `/v3/database/:collection` (objeto completo) |
|
|
81
|
+
| Delete | DELETE | `/v3/database/:collection?q=...` |
|
|
82
|
+
| Bulk | POST | `/v3/database/:collection/bulk` |
|
|
33
83
|
|
|
34
|
-
**Exemplo — Criar item na coleção `car__c`:**
|
|
35
84
|
```
|
|
36
85
|
POST /v3/database/car__c
|
|
86
|
+
{ "_id": "car001", "name": "Civic", "brand": "Honda", "price": 50000 }
|
|
37
87
|
```
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"_id": "car001",
|
|
41
|
-
"name": "Civic",
|
|
42
|
-
"brand": "Honda",
|
|
43
|
-
"price": 50000
|
|
44
|
-
}
|
|
88
|
+
|
|
89
|
+
**Filtrar** (param `q`, sintaxe Mongo — ver §1.5):
|
|
45
90
|
```
|
|
91
|
+
GET /v3/database/profile__c?strict=true&q=_id:'john'
|
|
92
|
+
```
|
|
93
|
+
> A resposta de um `q=_id:` é um **array** — normalize pegando `[0]` (`patterns.md` §10).
|
|
46
94
|
|
|
47
|
-
|
|
95
|
+
**Aggregate** (mecânica aqui; pipelines em `aggregates.md`):
|
|
96
|
+
```
|
|
97
|
+
POST /v3/database/:collection/aggregate
|
|
98
|
+
[ { "$match": { "type": 0 } }, { "$group": { "_id": null, "total": { "$sum": "$total" } } } ]
|
|
99
|
+
```
|
|
48
100
|
|
|
49
|
-
|
|
50
|
-
**Endpoint:** `/v3/database/:collection/aggregate`
|
|
101
|
+
### Armadilhas conhecidas
|
|
51
102
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
{ "$match": { "player": "john", "type": 0, "item": "xp" } },
|
|
56
|
-
{ "$group": { "_id": null, "totalXP": { "$sum": "$total" } } }
|
|
57
|
-
]
|
|
58
|
-
```
|
|
103
|
+
- **`_filter`/`_sort`/`_limit`** → ignorados (§1.5). Correção: `q` + aggregate `$sort`.
|
|
104
|
+
- **`PUT` parcial** → replace apaga campos (§1.5). Correção: objeto completo.
|
|
105
|
+
- **`POST` esperando busca** → cria documento (§1.5). Correção: `GET ?q=`.
|
|
59
106
|
|
|
60
|
-
|
|
61
|
-
```json
|
|
62
|
-
[{ "totalXP": 250 }]
|
|
63
|
-
```
|
|
107
|
+
---
|
|
64
108
|
|
|
65
|
-
|
|
109
|
+
## 3. Acesso via Código (Jongo)
|
|
66
110
|
|
|
67
|
-
|
|
111
|
+
Quando usar: ler/escrever coleções dentro de trigger, scheduler ou public endpoint.
|
|
112
|
+
Não usar quando: existir um manager para a operação → `java-managers.md`.
|
|
113
|
+
Depende de: `database` (param do trigger) ou `manager.getJongoConnection()`.
|
|
114
|
+
Disponível em: Todos (em Public Endpoint via `manager.getJongoConnection()` — `patterns.md` §6).
|
|
68
115
|
|
|
69
|
-
|
|
70
|
-
|----------|--------|----------|
|
|
71
|
-
| Listar | GET | `/v3/database/:collection/index` |
|
|
72
|
-
| Criar | POST | `/v3/database/:collection/index` |
|
|
73
|
-
| Excluir | DELETE | `/v3/database/:collection/index/:index_name` |
|
|
116
|
+
### Descrição
|
|
74
117
|
|
|
75
|
-
**
|
|
76
|
-
|
|
77
|
-
|
|
118
|
+
Acesso direto ao MongoDB via driver Jongo. Em **triggers** use o param `database`; em **schedulers/public endpoints** (que não recebem `database`) use `manager.getJongoConnection()`. Ambos retornam o mesmo tipo de coleção.
|
|
119
|
+
|
|
120
|
+
### Uso
|
|
121
|
+
|
|
122
|
+
```java
|
|
123
|
+
// --- Obter coleção ---
|
|
124
|
+
database.getCollection("car__c"); // em trigger
|
|
125
|
+
manager.getJongoConnection().getCollection("car__c"); // em scheduler/endpoint
|
|
126
|
+
|
|
127
|
+
// --- SAVE (insere ou atualiza se _id existir) ---
|
|
128
|
+
database.getCollection("email__c").save(payload);
|
|
129
|
+
|
|
130
|
+
// --- FIND ---
|
|
131
|
+
Object one = database.getCollection("player").findOne("{_id: #}", "john").as(Map.class);
|
|
132
|
+
Iterable<Object> many = database.getCollection("action_log").find("{userId: #}", "john").as(Object.class);
|
|
133
|
+
|
|
134
|
+
// --- FIND com projeção ---
|
|
135
|
+
Object proj = database.getCollection("player")
|
|
136
|
+
.findOne("{_id: #}", id).projection("{name: 1, email: 1}").as(Object.class);
|
|
137
|
+
|
|
138
|
+
// --- COUNT ---
|
|
139
|
+
long total = database.getCollection("action_log").count("{userId: #}", "john");
|
|
140
|
+
|
|
141
|
+
// --- DELETE ---
|
|
142
|
+
database.getCollection("car__c").remove("{_id: #}", "car001");
|
|
143
|
+
|
|
144
|
+
// --- UPDATE (set parcial) ---
|
|
145
|
+
manager.getJongoConnection().getCollection("player").update("{_id: #}", playerId).with(setCmd);
|
|
78
146
|
```
|
|
79
147
|
|
|
148
|
+
> No Public Endpoint, escapar `$` de operadores Mongo (`patterns.md` §6):
|
|
149
|
+
> ```groovy
|
|
150
|
+
> def d = String.valueOf((char)0x24)
|
|
151
|
+
> def setCmd = '{"' + d + 'set": {"extra.plan.type": "premium"}}'
|
|
152
|
+
> ```
|
|
153
|
+
|
|
154
|
+
Para **aggregate via Jongo**, ver `aggregates.md` (a sintaxe `.aggregate(...).and(...)` é detalhada lá).
|
|
155
|
+
|
|
156
|
+
### Armadilhas conhecidas
|
|
157
|
+
|
|
158
|
+
- **`manager.getJongoConnection()` esperado em trigger** → funciona, mas o param `database` é mais curto. Prefira `database` em triggers.
|
|
159
|
+
- **`update(...).with(...)` sem `$set`** → substitui o documento. Correção: usar `$set` para atualização parcial.
|
|
160
|
+
|
|
80
161
|
---
|
|
81
162
|
|
|
82
|
-
##
|
|
163
|
+
## 4. Placeholders e Segurança
|
|
83
164
|
|
|
84
|
-
|
|
165
|
+
Quando usar: sempre que a query envolver valores dinâmicos.
|
|
166
|
+
Não usar quando: —
|
|
167
|
+
Depende de: —
|
|
168
|
+
Disponível em: Todos.
|
|
85
169
|
|
|
86
|
-
###
|
|
170
|
+
### Descrição
|
|
87
171
|
|
|
88
|
-
|
|
89
|
-
manager.getJongoConnection().getCollection("nome_da_colecao").operacao(...);
|
|
90
|
-
```
|
|
172
|
+
O Jongo usa `#` como placeholder posicional para parâmetros seguros, evitando injeção. Os valores substituem os `#` na ordem.
|
|
91
173
|
|
|
92
|
-
###
|
|
174
|
+
### Uso
|
|
93
175
|
|
|
94
|
-
#### Salvar (Insert/Update)
|
|
95
176
|
```java
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
.save(payload);
|
|
99
|
-
```
|
|
177
|
+
// Um parâmetro
|
|
178
|
+
database.getCollection("player").findOne("{_id: #}", playerId).as(Object.class);
|
|
100
179
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
.getCollection("player")
|
|
105
|
-
.findOne("{_id: 'john'}")
|
|
106
|
-
.as(Map.class);
|
|
180
|
+
// Múltiplos parâmetros (ordem importa)
|
|
181
|
+
database.getCollection("action_log")
|
|
182
|
+
.find("{userId: #, actionId: #}", "john", "sell").as(Object.class);
|
|
107
183
|
```
|
|
108
184
|
|
|
109
|
-
|
|
110
|
-
```java
|
|
111
|
-
manager.getJongoConnection()
|
|
112
|
-
.getCollection("car__c")
|
|
113
|
-
.remove("{_id: 'car001'}");
|
|
114
|
-
```
|
|
185
|
+
### Armadilhas conhecidas
|
|
115
186
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
Iterable<Map> resultado = manager.getJongoConnection()
|
|
119
|
-
.getCollection("action_log")
|
|
120
|
-
.aggregate("[{ $match: { item: 'xp' } }, { $group: { _id: '$player', total: { $sum: '$total' } } }]")
|
|
121
|
-
.as(Map.class);
|
|
122
|
-
```
|
|
187
|
+
- **Concatenar valores na string da query** → injeção. Correção: sempre `#` + argumento.
|
|
188
|
+
- **Número de `#` ≠ número de argumentos** → erro de parsing. Correção: alinhar quantidade e ordem.
|
|
123
189
|
|
|
124
190
|
---
|
|
125
191
|
|
|
126
|
-
##
|
|
192
|
+
## 5. Índices
|
|
193
|
+
|
|
194
|
+
Quando usar: otimizar consultas frequentes numa coleção.
|
|
195
|
+
Não usar quando: a coleção é pequena ou a consulta é pontual.
|
|
196
|
+
Depende de: token autenticado.
|
|
197
|
+
Disponível em: API REST.
|
|
198
|
+
|
|
199
|
+
### Descrição
|
|
200
|
+
|
|
201
|
+
Gestão de índices via REST.
|
|
202
|
+
|
|
203
|
+
### Uso
|
|
204
|
+
|
|
205
|
+
| Operação | Método | Endpoint |
|
|
206
|
+
|----------|--------|----------|
|
|
207
|
+
| Listar | GET | `/v3/database/:collection/index` |
|
|
208
|
+
| Criar | POST | `/v3/database/:collection/index` |
|
|
209
|
+
| Excluir | DELETE | `/v3/database/:collection/index/:index_name` |
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
POST /v3/database/car__c/index
|
|
213
|
+
{ "fuel": 1 }
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Armadilhas conhecidas
|
|
127
217
|
|
|
128
|
-
-
|
|
129
|
-
- Endpoints públicos não requerem token — usar com cautela
|
|
130
|
-
- Manipulação direta do banco afeta dados em **tempo real**
|
|
131
|
-
- Sempre testar em **ambiente de homologação** antes de aplicar em produção
|
|
132
|
-
- Coleções customizadas usam sufixo `__c` (ex: `car__c`, `email__c`)
|
|
218
|
+
- **Criar índice em ambiente de produção sob carga** → impacto momentâneo. Correção: validar em homologação primeiro (`modules/staging.md`).
|