@omnizap-system/omnizap 2.5.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (425) hide show
  1. package/.clusterfuzzlite/Dockerfile +10 -0
  2. package/.env.example +907 -0
  3. package/.github/codeql/codeql-config.yml +10 -0
  4. package/.github/dependabot.yml +35 -0
  5. package/.github/workflows/ci.yml +73 -0
  6. package/.github/workflows/codeql.yml +106 -0
  7. package/.github/workflows/db-migration-check.yml +98 -0
  8. package/.github/workflows/dependency-review.yml +22 -0
  9. package/.github/workflows/deploy.yml +95 -0
  10. package/.github/workflows/release.yml +106 -0
  11. package/.github/workflows/security-attest-provenance.yml +51 -0
  12. package/.github/workflows/security-gitleaks.yml +34 -0
  13. package/.github/workflows/security-runner-hardening.yml +31 -0
  14. package/.github/workflows/security-scorecard.yml +44 -0
  15. package/.github/workflows/security-zap-baseline.yml +44 -0
  16. package/.github/workflows/security-zap-full-scan.yml +43 -0
  17. package/.github/workflows/security-zizmor.yml +36 -0
  18. package/.github/workflows/wiki-sync.yml +44 -0
  19. package/.gitleaks.toml +15 -0
  20. package/.prettierrc +34 -0
  21. package/CODE_OF_CONDUCT.md +114 -0
  22. package/LICENSE +56 -0
  23. package/README.md +110 -0
  24. package/SECURITY.md +110 -0
  25. package/app/config/index.js +4 -0
  26. package/app/configParts/adminIdentity.js +92 -0
  27. package/app/configParts/baileysConfig.js +1818 -0
  28. package/app/configParts/groupUtils.js +692 -0
  29. package/app/configParts/loggerConfig.js +394 -0
  30. package/app/configParts/messagePersistenceService.js +305 -0
  31. package/app/connection/baileysCompatibility.test.js +40 -0
  32. package/app/connection/baileysDbAuthState.js +344 -0
  33. package/app/connection/socketController.js +2243 -0
  34. package/app/controllers/messageController.js +7 -0
  35. package/app/controllers/messagePipeline/commandMiddleware.js +146 -0
  36. package/app/controllers/messagePipeline/conversationMiddleware.js +183 -0
  37. package/app/controllers/messagePipeline/messagePipelineMiddlewares.test.js +522 -0
  38. package/app/controllers/messagePipeline/postProcessingMiddleware.js +41 -0
  39. package/app/controllers/messagePipeline/preProcessingMiddlewares.js +166 -0
  40. package/app/controllers/messageProcessingPipeline.js +699 -0
  41. package/app/modules/adminModule/AGENT.md +4056 -0
  42. package/app/modules/adminModule/adminAiHelpService.js +56 -0
  43. package/app/modules/adminModule/adminConfigRuntime.js +177 -0
  44. package/app/modules/adminModule/commandConfig.json +7122 -0
  45. package/app/modules/adminModule/groupCommandHandlers.js +1823 -0
  46. package/app/modules/adminModule/groupCommandHandlers.test.js +350 -0
  47. package/app/modules/adminModule/groupEventHandlers.js +399 -0
  48. package/app/modules/aiModule/AGENT.md +547 -0
  49. package/app/modules/aiModule/aiAiHelpService.js +14 -0
  50. package/app/modules/aiModule/aiConfigRuntime.js +135 -0
  51. package/app/modules/aiModule/catCommand.js +967 -0
  52. package/app/modules/aiModule/commandConfig.json +981 -0
  53. package/app/modules/analyticsModule/messageAnalysisEventRepository.js +83 -0
  54. package/app/modules/gameModule/AGENT.md +196 -0
  55. package/app/modules/gameModule/commandConfig.json +366 -0
  56. package/app/modules/gameModule/diceCommand.js +42 -0
  57. package/app/modules/gameModule/gameAiHelpService.js +14 -0
  58. package/app/modules/gameModule/gameConfigRuntime.js +68 -0
  59. package/app/modules/menuModule/AGENT.md +205 -0
  60. package/app/modules/menuModule/commandConfig.json +366 -0
  61. package/app/modules/menuModule/common.js +316 -0
  62. package/app/modules/menuModule/menuAiHelpService.js +14 -0
  63. package/app/modules/menuModule/menuConfigRuntime.js +68 -0
  64. package/app/modules/menuModule/menus.js +66 -0
  65. package/app/modules/playModule/AGENT.md +321 -0
  66. package/app/modules/playModule/commandConfig.json +584 -0
  67. package/app/modules/playModule/playAiHelpService.js +14 -0
  68. package/app/modules/playModule/playCommand.js +1417 -0
  69. package/app/modules/playModule/playConfigRuntime.js +68 -0
  70. package/app/modules/quoteModule/AGENT.md +199 -0
  71. package/app/modules/quoteModule/commandConfig.json +366 -0
  72. package/app/modules/quoteModule/quoteAiHelpService.js +14 -0
  73. package/app/modules/quoteModule/quoteCommand.js +842 -0
  74. package/app/modules/quoteModule/quoteConfigRuntime.js +68 -0
  75. package/app/modules/rpgPokemonModule/AGENT.md +229 -0
  76. package/app/modules/rpgPokemonModule/commandConfig.json +386 -0
  77. package/app/modules/rpgPokemonModule/rpgBattleCanvasRenderer.js +795 -0
  78. package/app/modules/rpgPokemonModule/rpgBattleService.js +2110 -0
  79. package/app/modules/rpgPokemonModule/rpgBattleService.test.js +770 -0
  80. package/app/modules/rpgPokemonModule/rpgEvolutionUtils.js +22 -0
  81. package/app/modules/rpgPokemonModule/rpgPokemonAiHelpService.js +14 -0
  82. package/app/modules/rpgPokemonModule/rpgPokemonCommand.js +174 -0
  83. package/app/modules/rpgPokemonModule/rpgPokemonConfigRuntime.js +68 -0
  84. package/app/modules/rpgPokemonModule/rpgPokemonDomain.js +192 -0
  85. package/app/modules/rpgPokemonModule/rpgPokemonDomain.test.js +93 -0
  86. package/app/modules/rpgPokemonModule/rpgPokemonEvolution.test.js +46 -0
  87. package/app/modules/rpgPokemonModule/rpgPokemonMessages.js +746 -0
  88. package/app/modules/rpgPokemonModule/rpgPokemonRepository.js +1847 -0
  89. package/app/modules/rpgPokemonModule/rpgPokemonService.js +6839 -0
  90. package/app/modules/rpgPokemonModule/rpgProfileCanvasRenderer.js +354 -0
  91. package/app/modules/statsModule/AGENT.md +320 -0
  92. package/app/modules/statsModule/commandConfig.json +540 -0
  93. package/app/modules/statsModule/globalRankingCommand.js +64 -0
  94. package/app/modules/statsModule/rankingCommand.js +41 -0
  95. package/app/modules/statsModule/rankingCommon.js +1305 -0
  96. package/app/modules/statsModule/statsAiHelpService.js +14 -0
  97. package/app/modules/statsModule/statsConfigRuntime.js +68 -0
  98. package/app/modules/stickerModule/AGENT.md +692 -0
  99. package/app/modules/stickerModule/addStickerMetadata.js +239 -0
  100. package/app/modules/stickerModule/commandConfig.json +1216 -0
  101. package/app/modules/stickerModule/convertToWebp.js +367 -0
  102. package/app/modules/stickerModule/stickerAiHelpService.js +14 -0
  103. package/app/modules/stickerModule/stickerCommand.js +446 -0
  104. package/app/modules/stickerModule/stickerConfigRuntime.js +68 -0
  105. package/app/modules/stickerModule/stickerConvertCommand.js +159 -0
  106. package/app/modules/stickerModule/stickerTextCommand.js +653 -0
  107. package/app/modules/stickerPackModule/AGENT.md +215 -0
  108. package/app/modules/stickerPackModule/autoPackCollectorRuntime.js +20 -0
  109. package/app/modules/stickerPackModule/autoPackCollectorService.js +357 -0
  110. package/app/modules/stickerPackModule/commandConfig.json +387 -0
  111. package/app/modules/stickerPackModule/domainEventOutboxRepository.js +227 -0
  112. package/app/modules/stickerPackModule/domainEvents.js +52 -0
  113. package/app/modules/stickerPackModule/semanticReclassificationEngine.js +429 -0
  114. package/app/modules/stickerPackModule/semanticReclassificationEngine.test.js +75 -0
  115. package/app/modules/stickerPackModule/semanticThemeClusterService.js +544 -0
  116. package/app/modules/stickerPackModule/stickerAssetClassificationRepository.js +400 -0
  117. package/app/modules/stickerPackModule/stickerAssetRepository.js +400 -0
  118. package/app/modules/stickerPackModule/stickerAssetReprocessQueueRepository.js +175 -0
  119. package/app/modules/stickerPackModule/stickerAutoPackByTagsRuntime.js +3702 -0
  120. package/app/modules/stickerPackModule/stickerClassificationBackgroundRuntime.js +559 -0
  121. package/app/modules/stickerPackModule/stickerClassificationService.js +557 -0
  122. package/app/modules/stickerPackModule/stickerDedicatedTaskWorkerRuntime.js +249 -0
  123. package/app/modules/stickerPackModule/stickerDomainEventBus.js +65 -0
  124. package/app/modules/stickerPackModule/stickerDomainEventConsumerRuntime.js +208 -0
  125. package/app/modules/stickerPackModule/stickerMarketplaceDriftService.js +99 -0
  126. package/app/modules/stickerPackModule/stickerObjectStorageService.js +285 -0
  127. package/app/modules/stickerPackModule/stickerPackAiHelpService.js +14 -0
  128. package/app/modules/stickerPackModule/stickerPackCommandHandlers.js +1148 -0
  129. package/app/modules/stickerPackModule/stickerPackConfigRuntime.js +68 -0
  130. package/app/modules/stickerPackModule/stickerPackEngagementRepository.js +152 -0
  131. package/app/modules/stickerPackModule/stickerPackErrors.js +30 -0
  132. package/app/modules/stickerPackModule/stickerPackInteractionEventRepository.js +101 -0
  133. package/app/modules/stickerPackModule/stickerPackItemRepository.js +432 -0
  134. package/app/modules/stickerPackModule/stickerPackMarketplaceService.js +313 -0
  135. package/app/modules/stickerPackModule/stickerPackMessageService.js +268 -0
  136. package/app/modules/stickerPackModule/stickerPackRepository.js +450 -0
  137. package/app/modules/stickerPackModule/stickerPackScoreSnapshotRepository.js +179 -0
  138. package/app/modules/stickerPackModule/stickerPackScoreSnapshotRuntime.js +271 -0
  139. package/app/modules/stickerPackModule/stickerPackService.js +733 -0
  140. package/app/modules/stickerPackModule/stickerPackServiceRuntime.js +32 -0
  141. package/app/modules/stickerPackModule/stickerPackUtils.js +107 -0
  142. package/app/modules/stickerPackModule/stickerStorageService.js +559 -0
  143. package/app/modules/stickerPackModule/stickerWorkerPipelineRuntime.js +242 -0
  144. package/app/modules/stickerPackModule/stickerWorkerTaskQueueRepository.js +242 -0
  145. package/app/modules/systemMetricsModule/AGENT.md +193 -0
  146. package/app/modules/systemMetricsModule/commandConfig.json +344 -0
  147. package/app/modules/systemMetricsModule/pingCommand.js +399 -0
  148. package/app/modules/systemMetricsModule/systemMetricsAiHelpService.js +14 -0
  149. package/app/modules/systemMetricsModule/systemMetricsConfigRuntime.js +68 -0
  150. package/app/modules/tiktokModule/AGENT.md +196 -0
  151. package/app/modules/tiktokModule/commandConfig.json +366 -0
  152. package/app/modules/tiktokModule/tiktokAiHelpService.js +14 -0
  153. package/app/modules/tiktokModule/tiktokCommand.js +716 -0
  154. package/app/modules/tiktokModule/tiktokConfigRuntime.js +68 -0
  155. package/app/modules/userModule/AGENT.md +200 -0
  156. package/app/modules/userModule/commandConfig.json +386 -0
  157. package/app/modules/userModule/userAiHelpService.js +14 -0
  158. package/app/modules/userModule/userCommand.js +1155 -0
  159. package/app/modules/userModule/userConfigRuntime.js +68 -0
  160. package/app/modules/waifuPicsModule/AGENT.md +431 -0
  161. package/app/modules/waifuPicsModule/commandConfig.json +780 -0
  162. package/app/modules/waifuPicsModule/waifuPicsAiHelpService.js +14 -0
  163. package/app/modules/waifuPicsModule/waifuPicsCommand.js +586 -0
  164. package/app/modules/waifuPicsModule/waifuPicsConfigRuntime.js +68 -0
  165. package/app/observability/metrics.js +766 -0
  166. package/app/services/ai/aiHelpResponseCacheRepository.js +280 -0
  167. package/app/services/ai/aiLearningRepository.js +400 -0
  168. package/app/services/ai/commandConfigEnrichmentRepository.js +769 -0
  169. package/app/services/ai/commandConfigEnrichmentService.js +452 -0
  170. package/app/services/ai/commandConfigValidationService.js +443 -0
  171. package/app/services/ai/commandToolBuilderService.js +192 -0
  172. package/app/services/ai/conversationRouterService.js +516 -0
  173. package/app/services/ai/geminiService.js +115 -0
  174. package/app/services/ai/geminiService.test.js +87 -0
  175. package/app/services/ai/globalModuleAiHelpService.js +1412 -0
  176. package/app/services/ai/globalToolCallingService.js +203 -0
  177. package/app/services/ai/messageCommandExecutionService.js +391 -0
  178. package/app/services/ai/moduleAiHelpCoreService.js +1099 -0
  179. package/app/services/ai/moduleAiHelpWrapperFactory.js +65 -0
  180. package/app/services/ai/moduleCommandConfigRuntimeService.js +113 -0
  181. package/app/services/ai/moduleToolExecutorService.js +464 -0
  182. package/app/services/ai/moduleToolRegistryService.js +178 -0
  183. package/app/services/ai/toolCandidateSelectorService.js +781 -0
  184. package/app/services/auth/googleWebLinkService.js +80 -0
  185. package/app/services/auth/whatsappLoginLinkService.js +230 -0
  186. package/app/services/external/pokeApiService.js +398 -0
  187. package/app/services/group/groupMetadataService.js +311 -0
  188. package/app/services/infra/dbWriteQueue.js +874 -0
  189. package/app/services/infra/featureFlagService.js +131 -0
  190. package/app/services/infra/queueUtils.js +55 -0
  191. package/app/services/messaging/captchaService.js +491 -0
  192. package/app/services/messaging/messagePersistenceService.js +1 -0
  193. package/app/services/messaging/newsBroadcastService.js +347 -0
  194. package/app/services/sticker/stickerFocusService.js +347 -0
  195. package/app/services/sticker/stickerFocusService.test.js +43 -0
  196. package/app/store/aiPromptStore.js +38 -0
  197. package/app/store/conversationSessionStore.js +131 -0
  198. package/app/store/groupConfigStore.js +58 -0
  199. package/app/store/premiumUserStore.js +54 -0
  200. package/app/utils/antiLink/antiLinkModule.js +700 -0
  201. package/app/utils/http/getImageBufferModule.js +18 -0
  202. package/app/utils/json/jsonSanitizer.js +113 -0
  203. package/app/utils/json/jsonSanitizer.test.js +40 -0
  204. package/app/utils/systemMetrics/systemMetricsModule.js +88 -0
  205. package/app/workers/aiLearningWorker.js +605 -0
  206. package/app/workers/commandConfigEnrichmentWorker.js +242 -0
  207. package/database/index.js +2075 -0
  208. package/database/init.js +151 -0
  209. package/database/migrations/.gitkeep +0 -0
  210. package/database/migrations/20260307_d0_hardening_down.sql +64 -0
  211. package/database/migrations/20260307_d0_hardening_up.sql +79 -0
  212. package/database/migrations/20260307_d1_terms_acceptance_down.sql +11 -0
  213. package/database/migrations/20260307_d1_terms_acceptance_up.sql +37 -0
  214. package/database/migrations/20260307_d2_auth_hardening_down.sql +75 -0
  215. package/database/migrations/20260307_d2_auth_hardening_up.sql +100 -0
  216. package/database/migrations/20260314_d7_canonical_sender_down.sql +53 -0
  217. package/database/migrations/20260314_d7_canonical_sender_up.sql +114 -0
  218. package/database/migrations/20260406_d30_security_analytics_down.sql +95 -0
  219. package/database/migrations/20260406_d30_security_analytics_up.sql +292 -0
  220. package/database/migrations/20260407_d31_web_google_session_token_hardening_down.sql +2 -0
  221. package/database/migrations/20260407_d31_web_google_session_token_hardening_up.sql +17 -0
  222. package/database/migrations/20260408_d32_ai_help_response_cache_down.sql +1 -0
  223. package/database/migrations/20260408_d32_ai_help_response_cache_up.sql +22 -0
  224. package/database/migrations/20260409_d33_ai_learning_tables_down.sql +4 -0
  225. package/database/migrations/20260409_d33_ai_learning_tables_up.sql +52 -0
  226. package/database/migrations/20260410_d34_command_config_enrichment_down.sql +3 -0
  227. package/database/migrations/20260410_d34_command_config_enrichment_up.sql +48 -0
  228. package/database/schema.sql +1186 -0
  229. package/docker-compose.yml +104 -0
  230. package/docs/audits/stickerCatalogController-out-of-scope.md +103 -0
  231. package/docs/audits/stickerCatalogController-symbols.md +58 -0
  232. package/docs/compliance/acceptable-use-policy-2026-03-07.md +35 -0
  233. package/docs/compliance/dpa-b2b-standard-2026-03-07.md +80 -0
  234. package/docs/compliance/monthly-compliance-checklist-2026-03-07.md +88 -0
  235. package/docs/compliance/notice-and-takedown-policy-2026-03-07.md +34 -0
  236. package/docs/compliance/privacy-policy-2026-03-07.md +75 -0
  237. package/docs/compliance/subprocessors-inventory-2026-03-07.md +16 -0
  238. package/docs/database/production-db-evolution-runbook-2026q1.md +365 -0
  239. package/docs/security/dsar-lgpd-runbook-2026-03-07.md +86 -0
  240. package/docs/security/incident-response-lgpd-anpd-runbook-2026-03-07.md +77 -0
  241. package/docs/security/network-hardening-runbook-2026-03-07.md +137 -0
  242. package/docs/seo/omnizap-seo-playbook-br-2026-02-28.md +238 -0
  243. package/docs/seo/satellite-page-template.md +116 -0
  244. package/docs/seo/satellite-pages-phase1.json +364 -0
  245. package/docs/wiki/Home.md +120 -0
  246. package/docs/wiki/pair-extraordinaire-2026-03-08.md +3 -0
  247. package/docs/wiki/recent-changes-2026-03-08.md +47 -0
  248. package/ecosystem.prod.config.cjs +135 -0
  249. package/eslint.config.js +89 -0
  250. package/index.js +488 -0
  251. package/ml/clip_classifier/Dockerfile +18 -0
  252. package/ml/clip_classifier/README.md +118 -0
  253. package/ml/clip_classifier/adaptive_scoring.py +40 -0
  254. package/ml/clip_classifier/classifier.py +654 -0
  255. package/ml/clip_classifier/embedding_store.py +481 -0
  256. package/ml/clip_classifier/env_loader.py +15 -0
  257. package/ml/clip_classifier/llm_label_expander.py +144 -0
  258. package/ml/clip_classifier/main.py +213 -0
  259. package/ml/clip_classifier/requirements.txt +10 -0
  260. package/ml/clip_classifier/similarity_engine.py +74 -0
  261. package/new-logo.png +0 -0
  262. package/observability/alert-rules.yml +60 -0
  263. package/observability/grafana/dashboards/omnizap-mysql.json +136 -0
  264. package/observability/grafana/dashboards/omnizap-overview.json +170 -0
  265. package/observability/grafana/provisioning/dashboards/dashboards.yml +11 -0
  266. package/observability/grafana/provisioning/datasources/datasources.yml +15 -0
  267. package/observability/loki-config.yml +38 -0
  268. package/observability/mysql-setup.sql +46 -0
  269. package/observability/prometheus.yml +35 -0
  270. package/observability/promtail-config.yml +84 -0
  271. package/observability/sticker-catalog-slo.md +83 -0
  272. package/observability/sticker-scale-hardening-rollout.md +128 -0
  273. package/package.json +144 -0
  274. package/public/apple-touch-icon.png +0 -0
  275. package/public/assets/css/commands-react.input.css +71 -0
  276. package/public/assets/css/create-pack-react.input.css +31 -0
  277. package/public/assets/css/home-react.input.css +106 -0
  278. package/public/assets/css/login-react.input.css +58 -0
  279. package/public/assets/css/stickers-react.input.css +18 -0
  280. package/public/assets/css/terms-react.input.css +115 -0
  281. package/public/assets/css/user-react.input.css +57 -0
  282. package/public/assets/images/brand-icon-192.png +0 -0
  283. package/public/assets/images/brand-logo-128.webp +0 -0
  284. package/public/assets/images/hero-banner-1280.jpg +0 -0
  285. package/public/comandos/commands-catalog.json +4517 -0
  286. package/public/css/api-docs.css +161 -0
  287. package/public/css/stickers-admin.css +1288 -0
  288. package/public/css/styles.css +679 -0
  289. package/public/css/systemadm/admin.css +474 -0
  290. package/public/css/systemadm/base.css +73 -0
  291. package/public/css/systemadm/components.css +662 -0
  292. package/public/css/systemadm/layout.css +229 -0
  293. package/public/css/systemadm/tokens.css +56 -0
  294. package/public/favicon-16x16.png +0 -0
  295. package/public/favicon-32x32.png +0 -0
  296. package/public/favicon.ico +0 -0
  297. package/public/js/apps/apiDocsApp.js +235 -0
  298. package/public/js/apps/commandsReactApp.js +528 -0
  299. package/public/js/apps/createPackApp.js +1646 -0
  300. package/public/js/apps/homeReactApp.js +942 -0
  301. package/public/js/apps/loginReactApp.js +496 -0
  302. package/public/js/apps/stickersAdminApp.js +1753 -0
  303. package/public/js/apps/stickersApp.js +3797 -0
  304. package/public/js/apps/termsReactApp.js +528 -0
  305. package/public/js/apps/userApp.js +2540 -0
  306. package/public/js/apps/userProfile/actions.js +66 -0
  307. package/public/js/apps/userReactApp.js +547 -0
  308. package/public/js/catalog.js +950 -0
  309. package/public/pages/api-docs.html +40 -0
  310. package/public/pages/aup.html +158 -0
  311. package/public/pages/comandos.html +41 -0
  312. package/public/pages/dpa.html +227 -0
  313. package/public/pages/home.html +45 -0
  314. package/public/pages/licenca.html +182 -0
  315. package/public/pages/login.html +40 -0
  316. package/public/pages/notice-and-takedown.html +234 -0
  317. package/public/pages/politica-de-privacidade.html +251 -0
  318. package/public/pages/seo-bot-whatsapp-para-grupo.html +350 -0
  319. package/public/pages/seo-bot-whatsapp-sem-programar.html +350 -0
  320. package/public/pages/seo-como-automatizar-avisos-no-whatsapp.html +350 -0
  321. package/public/pages/seo-como-criar-comandos-whatsapp.html +350 -0
  322. package/public/pages/seo-como-evitar-spam-no-whatsapp.html +350 -0
  323. package/public/pages/seo-como-moderar-grupo-whatsapp.html +350 -0
  324. package/public/pages/seo-como-organizar-comunidade-whatsapp.html +350 -0
  325. package/public/pages/seo-melhor-bot-whatsapp-para-grupos.html +350 -0
  326. package/public/pages/stickers-admin.html +31 -0
  327. package/public/pages/stickers-create.html +41 -0
  328. package/public/pages/stickers.html +45 -0
  329. package/public/pages/suboperadores.html +237 -0
  330. package/public/pages/termos-de-uso-texto-integral.html +241 -0
  331. package/public/pages/termos-de-uso.html +41 -0
  332. package/public/pages/user-password-reset.html +32 -0
  333. package/public/pages/user-systemadm.html +508 -0
  334. package/public/pages/user.html +39 -0
  335. package/public/robots.txt +9 -0
  336. package/public/site.webmanifest +24 -0
  337. package/public/sitemap.xml +98 -0
  338. package/schemas/command-config.schema.json +582 -0
  339. package/scripts/baileys-compat-smoke.mjs +12 -0
  340. package/scripts/cache-bust.mjs +142 -0
  341. package/scripts/deploy.sh +916 -0
  342. package/scripts/email-broadcast-terms-update.mjs +170 -0
  343. package/scripts/enrich-command-discovery-fields.mjs +286 -0
  344. package/scripts/generate-command-config-schema.mjs +273 -0
  345. package/scripts/generate-commands-catalog.mjs +308 -0
  346. package/scripts/generate-module-agents.mjs +631 -0
  347. package/scripts/generate-seo-satellite-pages.mjs +400 -0
  348. package/scripts/github-deploy-notify.mjs +174 -0
  349. package/scripts/github-release-notify.mjs +219 -0
  350. package/scripts/release.sh +599 -0
  351. package/scripts/run-codeql-local.sh +116 -0
  352. package/scripts/run-prettier-all.mjs +25 -0
  353. package/scripts/security-smoketest.mjs +581 -0
  354. package/scripts/sticker-catalog-loadtest.mjs +210 -0
  355. package/scripts/sticker-worker-task.mjs +119 -0
  356. package/scripts/sync-readme-snapshot.mjs +133 -0
  357. package/scripts/validate-command-config-schema.mjs +130 -0
  358. package/scripts/validate-command-configs.mjs +15 -0
  359. package/scripts/wiki-sync.sh +191 -0
  360. package/server/auth/googleWebAuth/googleWebAuthRuntime.js +62 -0
  361. package/server/auth/googleWebAuth/googleWebAuthService.js +807 -0
  362. package/server/auth/jwt/webJwtService.js +147 -0
  363. package/server/auth/stickerCatalogAuthContext.js +165 -0
  364. package/server/auth/termsAcceptance/termsAcceptanceHandler.js +189 -0
  365. package/server/auth/userPassword/index.js +14 -0
  366. package/server/auth/userPassword/userPasswordAuthService.js +422 -0
  367. package/server/auth/userPassword/userPasswordCrypto.js +199 -0
  368. package/server/auth/userPassword/userPasswordCrypto.test.js +76 -0
  369. package/server/auth/userPassword/userPasswordRecoveryService.js +728 -0
  370. package/server/auth/validation/authSchemas.js +236 -0
  371. package/server/auth/webAccount/webAccountHandlers.js +1434 -0
  372. package/server/controllers/admin/adminBanService.js +138 -0
  373. package/server/controllers/admin/adminPanelHandlers.js +2083 -0
  374. package/server/controllers/admin/stickerCatalogAdminContext.js +17 -0
  375. package/server/controllers/admin/systemAdminController.js +201 -0
  376. package/server/controllers/email/emailAutomationController.js +239 -0
  377. package/server/controllers/metricsController.js +21 -0
  378. package/server/controllers/seo/stickerCatalogSeoContext.js +514 -0
  379. package/server/controllers/sticker/nonCatalogHandlers.js +303 -0
  380. package/server/controllers/sticker/stickerCatalogController.js +4700 -0
  381. package/server/controllers/system/contactController.js +115 -0
  382. package/server/controllers/system/githubController.js +137 -0
  383. package/server/controllers/system/stickerCatalogSystemContext.js +758 -0
  384. package/server/controllers/system/storageController.js +154 -0
  385. package/server/controllers/system/systemController.js +135 -0
  386. package/server/controllers/system/systemMetricsController.js +156 -0
  387. package/server/controllers/system/visitController.js +90 -0
  388. package/server/controllers/userController.js +145 -0
  389. package/server/email/emailAutomationRuntime.js +225 -0
  390. package/server/email/emailAutomationService.js +125 -0
  391. package/server/email/emailOutboxRepository.js +282 -0
  392. package/server/email/emailTemplateService.js +480 -0
  393. package/server/email/emailTransportService.js +156 -0
  394. package/server/http/clientIp.js +95 -0
  395. package/server/http/httpRequestUtils.js +262 -0
  396. package/server/http/httpRequestUtils.test.js +80 -0
  397. package/server/http/httpServer.js +180 -0
  398. package/server/http/requestContext.js +20 -0
  399. package/server/http/siteRoutingUtils.js +87 -0
  400. package/server/index.js +1 -0
  401. package/server/middleware/cachePolicy.js +26 -0
  402. package/server/middleware/cachePolicyHelpers.js +1 -0
  403. package/server/middleware/endpointRateLimit.js +181 -0
  404. package/server/middleware/rateLimit.js +70 -0
  405. package/server/middleware/requireAdminAuth.js +48 -0
  406. package/server/middleware/securityHeaders.js +97 -0
  407. package/server/routes/admin/systemAdminRouter.js +64 -0
  408. package/server/routes/email/emailAutomationRouter.js +46 -0
  409. package/server/routes/health/healthRouter.js +41 -0
  410. package/server/routes/indexRouter.js +234 -0
  411. package/server/routes/metrics/metricsRouter.js +58 -0
  412. package/server/routes/static/staticPageRouter.js +134 -0
  413. package/server/routes/sticker/catalogHandlers/catalogAdminHttp.js +105 -0
  414. package/server/routes/sticker/catalogHandlers/catalogAuthHttp.js +77 -0
  415. package/server/routes/sticker/catalogHandlers/catalogPublicHttp.js +120 -0
  416. package/server/routes/sticker/catalogHandlers/catalogUploadHttp.js +83 -0
  417. package/server/routes/sticker/catalogRouter.js +77 -0
  418. package/server/routes/sticker/stickerApiRouter.js +84 -0
  419. package/server/routes/sticker/stickerDataRouter.js +145 -0
  420. package/server/routes/sticker/stickerSiteRouter.js +43 -0
  421. package/server/routes/user/userApiPaths.js +66 -0
  422. package/server/routes/user/userRouter.js +65 -0
  423. package/server/utils/safePath.js +26 -0
  424. package/utils/logger/loggerModule.js +35 -0
  425. package/vite.config.mjs +38 -0
@@ -0,0 +1,83 @@
1
+ import { executeQuery, TABLES } from '../../../database/index.js';
2
+
3
+ const sanitizeText = (value, maxLength = 255) => {
4
+ const normalized = String(value || '')
5
+ .trim()
6
+ .replace(/\s+/g, ' ')
7
+ .slice(0, maxLength);
8
+ return normalized || null;
9
+ };
10
+
11
+ const sanitizeCommandName = (value) => {
12
+ const normalized = String(value || '')
13
+ .trim()
14
+ .toLowerCase()
15
+ .replace(/[^a-z0-9_-]/g, '')
16
+ .slice(0, 64);
17
+ return normalized || null;
18
+ };
19
+
20
+ const sanitizeBool = (value) => (value ? 1 : 0);
21
+
22
+ const clampInt = (value, fallback, min, max) => {
23
+ const numeric = Number(value);
24
+ if (!Number.isFinite(numeric)) return fallback;
25
+ return Math.max(min, Math.min(max, Math.floor(numeric)));
26
+ };
27
+
28
+ const sanitizeMetadata = (value) => {
29
+ if (!value || typeof value !== 'object') return null;
30
+ try {
31
+ const asJson = JSON.stringify(value);
32
+ if (!asJson || asJson === '{}') return null;
33
+ return asJson;
34
+ } catch {
35
+ return null;
36
+ }
37
+ };
38
+
39
+ export async function createMessageAnalysisEvent(payload = {}, connection = null) {
40
+ const messageId = sanitizeText(payload.messageId, 255);
41
+ const chatId = sanitizeText(payload.chatId, 255);
42
+ const senderId = sanitizeText(payload.senderId, 255);
43
+ const senderName = sanitizeText(payload.senderName, 120);
44
+ const upsertType = sanitizeText(payload.upsertType, 32);
45
+ const source = sanitizeText(payload.source, 32) || 'whatsapp';
46
+ const commandPrefix = sanitizeText(payload.commandPrefix, 8);
47
+ const commandName = sanitizeCommandName(payload.commandName);
48
+ const messageKind = sanitizeText(payload.messageKind, 48) || 'other';
49
+ const processingResult = sanitizeText(payload.processingResult, 64) || 'processed';
50
+ const errorCode = sanitizeText(payload.errorCode, 96);
51
+ const metadata = sanitizeMetadata(payload.metadata);
52
+
53
+ await executeQuery(
54
+ `INSERT INTO ${TABLES.MESSAGE_ANALYSIS_EVENT}
55
+ (
56
+ message_id,
57
+ chat_id,
58
+ sender_id,
59
+ sender_name,
60
+ upsert_type,
61
+ source,
62
+ is_group,
63
+ is_from_bot,
64
+ is_command,
65
+ command_name,
66
+ command_args_count,
67
+ command_known,
68
+ command_prefix,
69
+ message_kind,
70
+ has_media,
71
+ media_count,
72
+ text_length,
73
+ processing_result,
74
+ error_code,
75
+ metadata
76
+ )
77
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
78
+ [messageId, chatId, senderId, senderName, upsertType, source, sanitizeBool(payload.isGroup), sanitizeBool(payload.isFromBot), sanitizeBool(payload.isCommand), commandName, clampInt(payload.commandArgsCount, 0, 0, 64), payload.commandKnown === null || payload.commandKnown === undefined ? null : sanitizeBool(payload.commandKnown), commandPrefix, messageKind, sanitizeBool(payload.hasMedia), clampInt(payload.mediaCount, 0, 0, 25), clampInt(payload.textLength, 0, 0, 16_000), processingResult, errorCode, metadata],
79
+ connection,
80
+ );
81
+
82
+ return true;
83
+ }
@@ -0,0 +1,196 @@
1
+ # GameModule Agent Guide
2
+
3
+ Este arquivo e destinado a agentes de IA para gerar respostas no contexto dos comandos deste modulo.
4
+
5
+ ## Fonte de Verdade
6
+
7
+ - arquivo_base: `app/modules/gameModule/commandConfig.json`
8
+ - schema_version: `2.0.0`
9
+ - module_enabled: `true`
10
+ - generated_at: `2026-03-11T02:35:17.177Z`
11
+
12
+ ## Escopo do Modulo
13
+
14
+ - module: `gameModule`
15
+ - source_files:
16
+ - diceCommand.js
17
+ - total_commands: `1`
18
+ - total_enabled_commands: `1`
19
+
20
+ ## Defaults Schema v2
21
+
22
+ - inheritance_mode: deep_merge_with_command_overrides
23
+ - compatibility_mode: legacy_and_v2_fields
24
+ - legacy_field_aliases:
25
+ - descricao: description
26
+ - metodos_de_uso: usage
27
+ - permissao_necessaria: permission
28
+ - local_de_uso: contexts
29
+ - informacoes_coletadas: collected_data
30
+ - pre_condicoes: requirements
31
+ - dependencias_externas: dependencies
32
+ - efeitos_colaterais: side_effects
33
+ - observabilidade: observability
34
+ - privacidade: privacy
35
+ - limite_uso_por_plano: plan_limits
36
+ - argumentos: arguments
37
+ - acesso: access
38
+ - defaults.command:
39
+ - enabled: true
40
+ - category: jogos
41
+ - version: 1.0.0
42
+ - stability: stable
43
+ - deprecated: false
44
+ - replaced_by: null
45
+ - risk_level: medium
46
+ - defaults.requirements (legacy view):
47
+ - requer_grupo: nao
48
+ - requer_admin: nao
49
+ - requer_admin_principal: nao
50
+ - requer_google_login: sim
51
+ - requer_nsfw: nao
52
+ - requer_midia: nao
53
+ - requer_mensagem_respondida: nao
54
+
55
+ ## Protocolo de Resposta para IA
56
+
57
+ - Passo 1: identificar comando pelo token apos o prefixo.
58
+ - Passo 2: resolver alias para nome canonico usando campo `aliases`.
59
+ - Passo 3: validar `enabled`, `pre_condicoes`, permissao e local de uso.
60
+ - Passo 4: se houver erro de uso, responder com `mensagens_uso` (quando existir) ou `metodos_de_uso`.
61
+ - Passo 5: seguir `respostas_padrao` como fallback de texto.
62
+ - Passo 6: considerar `informacoes_coletadas`, `privacidade` e `observabilidade` ao elaborar resposta.
63
+
64
+ ## Regras de Seguranca para IA
65
+
66
+ - A IA orienta, mas nao executa acao administrativa automaticamente.
67
+ - Nao inventar comandos, subcomandos ou permissao fora do JSON.
68
+ - Sempre informar onde pode usar (grupo/privado) e quem pode usar.
69
+ - Em duvida de permissao, responder com orientacao conservadora.
70
+
71
+ ## Catalogo de Comandos
72
+
73
+ ### dado
74
+
75
+ - id: game.dado
76
+ - aliases: dice
77
+ - enabled: true
78
+ - categoria: jogos
79
+ - descricao: Rola um dado com numero de lados opcional.
80
+ - permissao_necessaria: usuario comum
81
+ - version: 1.0.0
82
+ - stability: stable
83
+ - deprecated: nao
84
+ - risk_level: low
85
+ - local_de_uso:
86
+ - privado
87
+ - grupo
88
+ - metodos_de_uso:
89
+ - <prefix>dado
90
+ - <prefix>dado 20
91
+ - <prefix>dice 100
92
+ - mensagens_uso (variantes):
93
+ - default:
94
+ - Formato de uso:
95
+ - <prefix>dado
96
+ - <prefix>dado <lados (2-1000)>
97
+ - <prefix>dice <lados (2-1000)>
98
+ - subcomandos:
99
+ - (nenhum)
100
+ - argumentos:
101
+ - lados | tipo: integer | opcional | validacao: 2 a 1000 | default: null | posicao: 0
102
+ - pre_condicoes:
103
+ - requer_grupo: nao
104
+ - requer_admin: nao
105
+ - requer_admin_principal: nao
106
+ - requer_google_login: sim
107
+ - requer_nsfw: nao
108
+ - requer_midia: nao
109
+ - requer_mensagem_respondida: nao
110
+ - rate_limit:
111
+ - max: null
112
+ - janela_ms: null
113
+ - escopo: sem_rate_limit_explicito
114
+ - acesso:
115
+ - somente_premium: nao
116
+ - planos_permitidos: comum, premium
117
+ - limite_uso_por_plano:
118
+ - comum: max=20, janela_ms=300000, escopo=usuario
119
+ - premium: max=75, janela_ms=300000, escopo=usuario
120
+ - informacoes_coletadas:
121
+ - identificador do chat (remoteJid)
122
+ - identificador do remetente (senderJid)
123
+ - texto do comando e argumentos
124
+ - contexto da mensagem (citacao e mencoes, quando existir)
125
+ - numero de lados informado no argumento (quando houver)
126
+ - dependencias_externas:
127
+ - (nenhum)
128
+ - efeitos_colaterais:
129
+ - gera número aleatório
130
+ - envia resultado no chat
131
+ - respostas_padrao:
132
+ - success: Comando executado com sucesso.
133
+ - usage_error: Formato de uso inválido. Consulte metodos_de_uso.
134
+ - permission_error: Permissão insuficiente para executar este comando.
135
+ - sucesso: Comando executado com sucesso.
136
+ - erro_uso: Formato de uso inválido. Consulte metodos_de_uso.
137
+ - erro_permissao: Permissão insuficiente para executar este comando.
138
+ - mensagens_sistema:
139
+ - (nao informado)
140
+ - limites_operacionais:
141
+ - (nao informado)
142
+ - opcoes:
143
+ - toggle_on_off_status.type: toggle
144
+ - toggle_on_off_status.allowed_actions: on, off, status
145
+ - toggle_on_off_status.action_argument: acao
146
+ - add_remove_list.type: list_management
147
+ - add_remove_list.allowed_actions: add, remove, list
148
+ - add_remove_list.action_argument: acao
149
+ - approve_reject.type: moderation_decision
150
+ - approve_reject.allowed_actions: approve, reject
151
+ - approve_reject.action_argument: acao
152
+ - approve_reject.requires_targets: true
153
+ - set_status_reset.type: configuration_window
154
+ - set_status_reset.allowed_actions: set, status, reset
155
+ - set_status_reset.action_argument: valor
156
+ - observabilidade:
157
+ - event_name: command.executed
158
+ - analytics_event: whatsapp_command_dado
159
+ - tags_log: whatsapp, command, gameModule, dado
160
+ - nivel_log: info
161
+ - privacidade:
162
+ - dados_sensiveis:
163
+ - chat_identifier
164
+ - sender_identifier
165
+ - command_content
166
+ - retencao: standard_app_logs
167
+ - base_legal: service_execution_and_legitimate_interest
168
+ - docs:
169
+ - summary: Rola um dado com numero de lados opcional.
170
+ - usage_examples: <prefix>dado, <prefix>dado 20, <prefix>dice 100
171
+ - usage_variants.default: Formato de uso:, <prefix>dado, <prefix>dado <lados (2-1000)>, <prefix>dice <lados (2-1000)>
172
+ - behavior:
173
+ - type: argument_driven
174
+ - allowed_actions: (nenhum)
175
+ - limits:
176
+ - usage_description: lados entre 2 e 1000
177
+ - rate_limit.max: null
178
+ - rate_limit.janela_ms: null
179
+ - rate_limit.escopo: sem_rate_limit_explicito
180
+ - access.somente_premium: false
181
+ - access.planos_permitidos: comum, premium
182
+ - plan_limits.comum.max: 20
183
+ - plan_limits.comum.janela_ms: 300000
184
+ - plan_limits.comum.escopo: usuario
185
+ - plan_limits.premium.max: 75
186
+ - plan_limits.premium.janela_ms: 300000
187
+ - plan_limits.premium.escopo: usuario
188
+ - discovery:
189
+ - keywords: dado, dice, jogos, privado, grupo
190
+ - faq_queries: como usar dado, o que faz dado, comando dado
191
+ - user_phrasings: quero usar dado, me ajuda com dado, rola um dado com
192
+ - suggestion_priority: 100
193
+ - handler:
194
+ - file: diceCommand.js
195
+ - method: handleDiceCommand
196
+ - command_case: dado
@@ -0,0 +1,366 @@
1
+ {
2
+ "schema_version": "2.0.0",
3
+ "module": "gameModule",
4
+ "enabled": true,
5
+ "source_files": ["diceCommand.js"],
6
+ "defaults": {
7
+ "inheritance_mode": "deep_merge_with_command_overrides",
8
+ "compatibility_mode": "legacy_and_v2_fields",
9
+ "legacy_field_aliases": {
10
+ "descricao": "description",
11
+ "metodos_de_uso": "usage",
12
+ "permissao_necessaria": "permission",
13
+ "local_de_uso": "contexts",
14
+ "informacoes_coletadas": "collected_data",
15
+ "pre_condicoes": "requirements",
16
+ "dependencias_externas": "dependencies",
17
+ "efeitos_colaterais": "side_effects",
18
+ "observabilidade": "observability",
19
+ "privacidade": "privacy",
20
+ "limite_uso_por_plano": "plan_limits",
21
+ "argumentos": "arguments",
22
+ "acesso": "access"
23
+ },
24
+ "command": {
25
+ "enabled": true,
26
+ "category": "jogos",
27
+ "version": "1.0.0",
28
+ "stability": "stable",
29
+ "deprecated": false,
30
+ "replaced_by": null,
31
+ "risk_level": "medium"
32
+ },
33
+ "requirements": {
34
+ "require_group": false,
35
+ "require_group_admin": false,
36
+ "require_bot_owner": false,
37
+ "require_google_login": true,
38
+ "require_nsfw_enabled": false,
39
+ "require_media": false,
40
+ "require_reply_message": false,
41
+ "legacy": {
42
+ "requer_grupo": false,
43
+ "requer_admin": false,
44
+ "requer_admin_principal": false,
45
+ "requer_google_login": true,
46
+ "requer_nsfw": false,
47
+ "requer_midia": false,
48
+ "requer_mensagem_respondida": false
49
+ }
50
+ },
51
+ "pre_condicoes": {
52
+ "requer_grupo": false,
53
+ "requer_admin": false,
54
+ "requer_admin_principal": false,
55
+ "requer_google_login": true,
56
+ "requer_nsfw": false,
57
+ "requer_midia": false,
58
+ "requer_mensagem_respondida": false
59
+ },
60
+ "rate_limit": {
61
+ "max": null,
62
+ "janela_ms": null,
63
+ "escopo": "sem_rate_limit_explicito"
64
+ },
65
+ "dependencies": [],
66
+ "dependencias_externas": [],
67
+ "responses": {
68
+ "success": "Comando executado com sucesso.",
69
+ "usage_error": "Formato de uso inválido. Consulte metodos_de_uso.",
70
+ "permission_error": "Permissão insuficiente para executar este comando."
71
+ },
72
+ "respostas_padrao": {
73
+ "sucesso": "Comando executado com sucesso.",
74
+ "erro_uso": "Formato de uso inválido. Consulte metodos_de_uso.",
75
+ "erro_permissao": "Permissão insuficiente para executar este comando."
76
+ },
77
+ "observability": {
78
+ "event_name": "command.executed",
79
+ "log_level": "info",
80
+ "tags": ["whatsapp", "command", "gameModule"]
81
+ },
82
+ "privacy": {
83
+ "data_categories": ["chat_identifier", "sender_identifier", "command_content"],
84
+ "retention_policy": "standard_app_logs",
85
+ "legal_basis": "service_execution_and_legitimate_interest"
86
+ },
87
+ "access": {
88
+ "premium_only": false,
89
+ "allowed_plans": ["comum", "premium"]
90
+ },
91
+ "acesso": {
92
+ "somente_premium": false,
93
+ "planos_permitidos": ["comum", "premium"]
94
+ },
95
+ "plan_limits": {
96
+ "comum": {
97
+ "max": 20,
98
+ "janela_ms": 300000,
99
+ "escopo": "usuario"
100
+ },
101
+ "premium": {
102
+ "max": 75,
103
+ "janela_ms": 300000,
104
+ "escopo": "usuario"
105
+ }
106
+ },
107
+ "limite_uso_por_plano": {
108
+ "comum": {
109
+ "max": 20,
110
+ "janela_ms": 300000,
111
+ "escopo": "usuario"
112
+ },
113
+ "premium": {
114
+ "max": 75,
115
+ "janela_ms": 300000,
116
+ "escopo": "usuario"
117
+ }
118
+ },
119
+ "behavior_templates": {
120
+ "toggle_on_off_status": {
121
+ "type": "toggle",
122
+ "allowed_actions": ["on", "off", "status"],
123
+ "action_argument": "acao"
124
+ },
125
+ "add_remove_list": {
126
+ "type": "list_management",
127
+ "allowed_actions": ["add", "remove", "list"],
128
+ "action_argument": "acao"
129
+ },
130
+ "approve_reject": {
131
+ "type": "moderation_decision",
132
+ "allowed_actions": ["approve", "reject"],
133
+ "action_argument": "acao",
134
+ "requires_targets": true
135
+ },
136
+ "set_status_reset": {
137
+ "type": "configuration_window",
138
+ "allowed_actions": ["set", "status", "reset"],
139
+ "action_argument": "valor"
140
+ }
141
+ }
142
+ },
143
+ "commands": [
144
+ {
145
+ "name": "dado",
146
+ "aliases": ["dice"],
147
+ "descricao": "Rola um dado com numero de lados opcional.",
148
+ "metodos_de_uso": ["<prefix>dado", "<prefix>dado 20", "<prefix>dice 100"],
149
+ "permissao_necessaria": "usuario comum",
150
+ "limite_de_uso": "lados entre 2 e 1000",
151
+ "local_de_uso": ["privado", "grupo"],
152
+ "informacoes_coletadas": ["identificador do chat (remoteJid)", "identificador do remetente (senderJid)", "texto do comando e argumentos", "contexto da mensagem (citacao e mencoes, quando existir)", "numero de lados informado no argumento (quando houver)"],
153
+ "enabled": true,
154
+ "categoria": "jogos",
155
+ "subcomandos": [],
156
+ "argumentos": [
157
+ {
158
+ "nome": "lados",
159
+ "tipo": "integer",
160
+ "obrigatorio": false,
161
+ "validacao": "2 a 1000",
162
+ "default": 6
163
+ }
164
+ ],
165
+ "pre_condicoes": {
166
+ "requer_grupo": false,
167
+ "requer_admin": false,
168
+ "requer_admin_principal": false,
169
+ "requer_google_login": true,
170
+ "requer_nsfw": false,
171
+ "requer_midia": false,
172
+ "requer_mensagem_respondida": false
173
+ },
174
+ "rate_limit": {
175
+ "max": null,
176
+ "janela_ms": null,
177
+ "escopo": "sem_rate_limit_explicito"
178
+ },
179
+ "dependencias_externas": [],
180
+ "efeitos_colaterais": ["gera número aleatório", "envia resultado no chat"],
181
+ "respostas_padrao": {
182
+ "sucesso": "Comando executado com sucesso.",
183
+ "erro_uso": "Formato de uso inválido. Consulte metodos_de_uso.",
184
+ "erro_permissao": "Permissão insuficiente para executar este comando."
185
+ },
186
+ "observabilidade": {
187
+ "evento_analytics": "whatsapp_command_dado",
188
+ "tags_log": ["whatsapp", "command", "gameModule", "dado"],
189
+ "nivel_log": "info"
190
+ },
191
+ "privacidade": {
192
+ "dados_sensiveis": ["identificador do chat", "identificador do remetente", "conteudo textual do comando"],
193
+ "retencao": "conforme políticas de logs, banco de dados e arquivos temporários da aplicação",
194
+ "base_legal": "execução do serviço solicitado e legítimo interesse operacional"
195
+ },
196
+ "capability_keywords": ["dado", "dice", "jogos", "privado", "grupo"],
197
+ "faq_patterns": ["como usar dado", "o que faz dado", "comando dado"],
198
+ "user_phrasings": ["quero usar dado", "me ajuda com dado", "rola um dado com"],
199
+ "suggestion_priority": 100,
200
+ "acesso": {
201
+ "somente_premium": false,
202
+ "planos_permitidos": ["comum", "premium"]
203
+ },
204
+ "limite_uso_por_plano": {
205
+ "comum": {
206
+ "max": 20,
207
+ "janela_ms": 300000,
208
+ "escopo": "usuario"
209
+ },
210
+ "premium": {
211
+ "max": 75,
212
+ "janela_ms": 300000,
213
+ "escopo": "usuario"
214
+ }
215
+ },
216
+ "mensagens_uso": {
217
+ "default": ["Formato de uso:", "<prefix>dado", "<prefix>dado <lados (2-1000)>", "<prefix>dice <lados (2-1000)>"]
218
+ },
219
+ "id": "game.dado",
220
+ "description": "Rola um dado com numero de lados opcional.",
221
+ "usage": ["<prefix>dado", "<prefix>dado 20", "<prefix>dice 100"],
222
+ "docs": {
223
+ "summary": "Rola um dado com numero de lados opcional.",
224
+ "usage_examples": ["<prefix>dado", "<prefix>dado 20", "<prefix>dice 100"],
225
+ "usage_variants": {
226
+ "default": ["Formato de uso:", "<prefix>dado", "<prefix>dado <lados (2-1000)>", "<prefix>dice <lados (2-1000)>"]
227
+ }
228
+ },
229
+ "permission": "usuario comum",
230
+ "contexts": ["privado", "grupo"],
231
+ "collected_data": ["identificador do chat (remoteJid)", "identificador do remetente (senderJid)", "texto do comando e argumentos", "contexto da mensagem (citacao e mencoes, quando existir)", "numero de lados informado no argumento (quando houver)"],
232
+ "requirements": {
233
+ "require_group": false,
234
+ "require_group_admin": false,
235
+ "require_bot_owner": false,
236
+ "require_google_login": true,
237
+ "require_nsfw_enabled": false,
238
+ "require_media": false,
239
+ "require_reply_message": false,
240
+ "legacy": {
241
+ "requer_grupo": false,
242
+ "requer_admin": false,
243
+ "requer_admin_principal": false,
244
+ "requer_google_login": true,
245
+ "requer_nsfw": false,
246
+ "requer_midia": false,
247
+ "requer_mensagem_respondida": false
248
+ }
249
+ },
250
+ "arguments": [
251
+ {
252
+ "name": "lados",
253
+ "type": "integer",
254
+ "required": false,
255
+ "default": 6,
256
+ "enum": null,
257
+ "description": "2 a 1000",
258
+ "position": 0,
259
+ "accepts_mentions": false,
260
+ "accepts_reply_target": false,
261
+ "greedy": false,
262
+ "validation": "2 a 1000"
263
+ }
264
+ ],
265
+ "behavior": {
266
+ "type": "argument_driven",
267
+ "allowed_actions": []
268
+ },
269
+ "limits": {
270
+ "usage_description": "lados entre 2 e 1000",
271
+ "rate_limit": {
272
+ "max": null,
273
+ "janela_ms": null,
274
+ "escopo": "sem_rate_limit_explicito"
275
+ },
276
+ "access": {
277
+ "somente_premium": false,
278
+ "planos_permitidos": ["comum", "premium"]
279
+ },
280
+ "plan_limits": {
281
+ "comum": {
282
+ "max": 20,
283
+ "janela_ms": 300000,
284
+ "escopo": "usuario"
285
+ },
286
+ "premium": {
287
+ "max": 75,
288
+ "janela_ms": 300000,
289
+ "escopo": "usuario"
290
+ }
291
+ }
292
+ },
293
+ "dependencies": [],
294
+ "side_effects": ["gera número aleatório", "envia resultado no chat"],
295
+ "observability": {
296
+ "event_name": "command.executed",
297
+ "event_key": "game.dado",
298
+ "analytics_event": "whatsapp_command_dado",
299
+ "log_level": "info",
300
+ "tags": ["whatsapp", "command", "gameModule", "dado"],
301
+ "legacy": {
302
+ "evento_analytics": "whatsapp_command_dado",
303
+ "tags_log": ["whatsapp", "command", "gameModule", "dado"],
304
+ "nivel_log": "info"
305
+ }
306
+ },
307
+ "privacy": {
308
+ "data_categories": ["chat_identifier", "sender_identifier", "command_content"],
309
+ "sensitive_fields": ["remoteJid", "senderJid", "text", "args"],
310
+ "retention_policy": "standard_app_logs",
311
+ "retention_notes": "conforme políticas de logs, banco de dados e arquivos temporários da aplicação",
312
+ "legal_basis": "service_execution_and_legitimate_interest",
313
+ "legal_basis_notes": "execução do serviço solicitado e legítimo interesse operacional",
314
+ "legacy": {
315
+ "dados_sensiveis": ["identificador do chat", "identificador do remetente", "conteudo textual do comando"],
316
+ "retencao": "conforme políticas de logs, banco de dados e arquivos temporários da aplicação",
317
+ "base_legal": "execução do serviço solicitado e legítimo interesse operacional"
318
+ }
319
+ },
320
+ "discovery": {
321
+ "keywords": ["dado", "dice", "jogos", "privado", "grupo"],
322
+ "faq_queries": ["como usar dado", "o que faz dado", "comando dado"],
323
+ "user_phrasings": ["quero usar dado", "me ajuda com dado", "rola um dado com"],
324
+ "suggestion_priority": 100
325
+ },
326
+ "access": {
327
+ "premium_only": false,
328
+ "allowed_plans": ["comum", "premium"],
329
+ "legacy": {
330
+ "somente_premium": false,
331
+ "planos_permitidos": ["comum", "premium"]
332
+ }
333
+ },
334
+ "plan_limits": {
335
+ "comum": {
336
+ "max": 20,
337
+ "janela_ms": 300000,
338
+ "escopo": "usuario"
339
+ },
340
+ "premium": {
341
+ "max": 75,
342
+ "janela_ms": 300000,
343
+ "escopo": "usuario"
344
+ }
345
+ },
346
+ "version": "1.0.0",
347
+ "stability": "stable",
348
+ "deprecated": false,
349
+ "replaced_by": null,
350
+ "risk_level": "low",
351
+ "handler": {
352
+ "file": "diceCommand.js",
353
+ "method": "handleDiceCommand",
354
+ "command_case": "dado"
355
+ },
356
+ "compatibility": {
357
+ "schema": "legacy_v1_and_v2",
358
+ "legacy_name": "dado",
359
+ "legacy_fields_present": ["descricao", "metodos_de_uso", "permissao_necessaria", "local_de_uso", "informacoes_coletadas", "argumentos", "pre_condicoes", "dependencias_externas", "efeitos_colaterais", "observabilidade", "privacidade", "acesso", "limite_uso_por_plano"]
360
+ }
361
+ }
362
+ ],
363
+ "textos": {
364
+ "usage_header": ""
365
+ }
366
+ }
@@ -0,0 +1,42 @@
1
+ import logger from '#logger';
2
+ import { sendAndStore } from '../../services/messaging/messagePersistenceService.js';
3
+ import { getGameUsageText } from './gameConfigRuntime.js';
4
+
5
+ const DICE_FACES = ['⚀', '⚁', '⚂', '⚃', '⚄', '⚅'];
6
+ const MAX_SIDES = 1000;
7
+
8
+ const parseSidesArgument = (rawArg) => {
9
+ if (!rawArg) return 6;
10
+ const parsed = Number.parseInt(rawArg, 10);
11
+ if (!Number.isFinite(parsed)) return null;
12
+ if (parsed < 2 || parsed > MAX_SIDES) return null;
13
+ return parsed;
14
+ };
15
+
16
+ const rollDice = (sides) => Math.floor(Math.random() * sides) + 1;
17
+
18
+ const buildUsageText = (commandPrefix) => getGameUsageText('dado', { commandPrefix }) || [`Formato de uso:`, `${commandPrefix}dado`, `${commandPrefix}dado <lados (2-${MAX_SIDES})>`, `${commandPrefix}dice <lados (2-${MAX_SIDES})>`].join('\n');
19
+
20
+ export async function handleDiceCommand({ sock, remoteJid, messageInfo, expirationMessage, args = [], commandPrefix = '/' }) {
21
+ const sides = parseSidesArgument(args[0]);
22
+ if (sides === null) {
23
+ await sendAndStore(sock, remoteJid, { text: `❌ Número de lados inválido.\n\n${buildUsageText(commandPrefix)}` }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
24
+ return;
25
+ }
26
+
27
+ const result = rollDice(sides);
28
+ const face = sides === 6 ? DICE_FACES[result - 1] : '🎲';
29
+ const messageText = sides === 6 ? `🎲 Você rolou o dado e caiu em *${result}* ${face}` : `🎲 Você rolou um dado de *${sides}* lados e caiu em *${result}*`;
30
+
31
+ try {
32
+ await sendAndStore(sock, remoteJid, { text: messageText }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
33
+ } catch (error) {
34
+ logger.error('handleDiceCommand: erro ao enviar resultado do dado.', {
35
+ error: error.message,
36
+ remoteJid,
37
+ sides,
38
+ result,
39
+ });
40
+ await sendAndStore(sock, remoteJid, { text: '❌ Não foi possível rolar o dado agora. Tente novamente.' }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
41
+ }
42
+ }