@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.
- package/.clusterfuzzlite/Dockerfile +10 -0
- package/.env.example +907 -0
- package/.github/codeql/codeql-config.yml +10 -0
- package/.github/dependabot.yml +35 -0
- package/.github/workflows/ci.yml +73 -0
- package/.github/workflows/codeql.yml +106 -0
- package/.github/workflows/db-migration-check.yml +98 -0
- package/.github/workflows/dependency-review.yml +22 -0
- package/.github/workflows/deploy.yml +95 -0
- package/.github/workflows/release.yml +106 -0
- package/.github/workflows/security-attest-provenance.yml +51 -0
- package/.github/workflows/security-gitleaks.yml +34 -0
- package/.github/workflows/security-runner-hardening.yml +31 -0
- package/.github/workflows/security-scorecard.yml +44 -0
- package/.github/workflows/security-zap-baseline.yml +44 -0
- package/.github/workflows/security-zap-full-scan.yml +43 -0
- package/.github/workflows/security-zizmor.yml +36 -0
- package/.github/workflows/wiki-sync.yml +44 -0
- package/.gitleaks.toml +15 -0
- package/.prettierrc +34 -0
- package/CODE_OF_CONDUCT.md +114 -0
- package/LICENSE +56 -0
- package/README.md +110 -0
- package/SECURITY.md +110 -0
- package/app/config/index.js +4 -0
- package/app/configParts/adminIdentity.js +92 -0
- package/app/configParts/baileysConfig.js +1818 -0
- package/app/configParts/groupUtils.js +692 -0
- package/app/configParts/loggerConfig.js +394 -0
- package/app/configParts/messagePersistenceService.js +305 -0
- package/app/connection/baileysCompatibility.test.js +40 -0
- package/app/connection/baileysDbAuthState.js +344 -0
- package/app/connection/socketController.js +2243 -0
- package/app/controllers/messageController.js +7 -0
- package/app/controllers/messagePipeline/commandMiddleware.js +146 -0
- package/app/controllers/messagePipeline/conversationMiddleware.js +183 -0
- package/app/controllers/messagePipeline/messagePipelineMiddlewares.test.js +522 -0
- package/app/controllers/messagePipeline/postProcessingMiddleware.js +41 -0
- package/app/controllers/messagePipeline/preProcessingMiddlewares.js +166 -0
- package/app/controllers/messageProcessingPipeline.js +699 -0
- package/app/modules/adminModule/AGENT.md +4056 -0
- package/app/modules/adminModule/adminAiHelpService.js +56 -0
- package/app/modules/adminModule/adminConfigRuntime.js +177 -0
- package/app/modules/adminModule/commandConfig.json +7122 -0
- package/app/modules/adminModule/groupCommandHandlers.js +1823 -0
- package/app/modules/adminModule/groupCommandHandlers.test.js +350 -0
- package/app/modules/adminModule/groupEventHandlers.js +399 -0
- package/app/modules/aiModule/AGENT.md +547 -0
- package/app/modules/aiModule/aiAiHelpService.js +14 -0
- package/app/modules/aiModule/aiConfigRuntime.js +135 -0
- package/app/modules/aiModule/catCommand.js +967 -0
- package/app/modules/aiModule/commandConfig.json +981 -0
- package/app/modules/analyticsModule/messageAnalysisEventRepository.js +83 -0
- package/app/modules/gameModule/AGENT.md +196 -0
- package/app/modules/gameModule/commandConfig.json +366 -0
- package/app/modules/gameModule/diceCommand.js +42 -0
- package/app/modules/gameModule/gameAiHelpService.js +14 -0
- package/app/modules/gameModule/gameConfigRuntime.js +68 -0
- package/app/modules/menuModule/AGENT.md +205 -0
- package/app/modules/menuModule/commandConfig.json +366 -0
- package/app/modules/menuModule/common.js +316 -0
- package/app/modules/menuModule/menuAiHelpService.js +14 -0
- package/app/modules/menuModule/menuConfigRuntime.js +68 -0
- package/app/modules/menuModule/menus.js +66 -0
- package/app/modules/playModule/AGENT.md +321 -0
- package/app/modules/playModule/commandConfig.json +584 -0
- package/app/modules/playModule/playAiHelpService.js +14 -0
- package/app/modules/playModule/playCommand.js +1417 -0
- package/app/modules/playModule/playConfigRuntime.js +68 -0
- package/app/modules/quoteModule/AGENT.md +199 -0
- package/app/modules/quoteModule/commandConfig.json +366 -0
- package/app/modules/quoteModule/quoteAiHelpService.js +14 -0
- package/app/modules/quoteModule/quoteCommand.js +842 -0
- package/app/modules/quoteModule/quoteConfigRuntime.js +68 -0
- package/app/modules/rpgPokemonModule/AGENT.md +229 -0
- package/app/modules/rpgPokemonModule/commandConfig.json +386 -0
- package/app/modules/rpgPokemonModule/rpgBattleCanvasRenderer.js +795 -0
- package/app/modules/rpgPokemonModule/rpgBattleService.js +2110 -0
- package/app/modules/rpgPokemonModule/rpgBattleService.test.js +770 -0
- package/app/modules/rpgPokemonModule/rpgEvolutionUtils.js +22 -0
- package/app/modules/rpgPokemonModule/rpgPokemonAiHelpService.js +14 -0
- package/app/modules/rpgPokemonModule/rpgPokemonCommand.js +174 -0
- package/app/modules/rpgPokemonModule/rpgPokemonConfigRuntime.js +68 -0
- package/app/modules/rpgPokemonModule/rpgPokemonDomain.js +192 -0
- package/app/modules/rpgPokemonModule/rpgPokemonDomain.test.js +93 -0
- package/app/modules/rpgPokemonModule/rpgPokemonEvolution.test.js +46 -0
- package/app/modules/rpgPokemonModule/rpgPokemonMessages.js +746 -0
- package/app/modules/rpgPokemonModule/rpgPokemonRepository.js +1847 -0
- package/app/modules/rpgPokemonModule/rpgPokemonService.js +6839 -0
- package/app/modules/rpgPokemonModule/rpgProfileCanvasRenderer.js +354 -0
- package/app/modules/statsModule/AGENT.md +320 -0
- package/app/modules/statsModule/commandConfig.json +540 -0
- package/app/modules/statsModule/globalRankingCommand.js +64 -0
- package/app/modules/statsModule/rankingCommand.js +41 -0
- package/app/modules/statsModule/rankingCommon.js +1305 -0
- package/app/modules/statsModule/statsAiHelpService.js +14 -0
- package/app/modules/statsModule/statsConfigRuntime.js +68 -0
- package/app/modules/stickerModule/AGENT.md +692 -0
- package/app/modules/stickerModule/addStickerMetadata.js +239 -0
- package/app/modules/stickerModule/commandConfig.json +1216 -0
- package/app/modules/stickerModule/convertToWebp.js +367 -0
- package/app/modules/stickerModule/stickerAiHelpService.js +14 -0
- package/app/modules/stickerModule/stickerCommand.js +446 -0
- package/app/modules/stickerModule/stickerConfigRuntime.js +68 -0
- package/app/modules/stickerModule/stickerConvertCommand.js +159 -0
- package/app/modules/stickerModule/stickerTextCommand.js +653 -0
- package/app/modules/stickerPackModule/AGENT.md +215 -0
- package/app/modules/stickerPackModule/autoPackCollectorRuntime.js +20 -0
- package/app/modules/stickerPackModule/autoPackCollectorService.js +357 -0
- package/app/modules/stickerPackModule/commandConfig.json +387 -0
- package/app/modules/stickerPackModule/domainEventOutboxRepository.js +227 -0
- package/app/modules/stickerPackModule/domainEvents.js +52 -0
- package/app/modules/stickerPackModule/semanticReclassificationEngine.js +429 -0
- package/app/modules/stickerPackModule/semanticReclassificationEngine.test.js +75 -0
- package/app/modules/stickerPackModule/semanticThemeClusterService.js +544 -0
- package/app/modules/stickerPackModule/stickerAssetClassificationRepository.js +400 -0
- package/app/modules/stickerPackModule/stickerAssetRepository.js +400 -0
- package/app/modules/stickerPackModule/stickerAssetReprocessQueueRepository.js +175 -0
- package/app/modules/stickerPackModule/stickerAutoPackByTagsRuntime.js +3702 -0
- package/app/modules/stickerPackModule/stickerClassificationBackgroundRuntime.js +559 -0
- package/app/modules/stickerPackModule/stickerClassificationService.js +557 -0
- package/app/modules/stickerPackModule/stickerDedicatedTaskWorkerRuntime.js +249 -0
- package/app/modules/stickerPackModule/stickerDomainEventBus.js +65 -0
- package/app/modules/stickerPackModule/stickerDomainEventConsumerRuntime.js +208 -0
- package/app/modules/stickerPackModule/stickerMarketplaceDriftService.js +99 -0
- package/app/modules/stickerPackModule/stickerObjectStorageService.js +285 -0
- package/app/modules/stickerPackModule/stickerPackAiHelpService.js +14 -0
- package/app/modules/stickerPackModule/stickerPackCommandHandlers.js +1148 -0
- package/app/modules/stickerPackModule/stickerPackConfigRuntime.js +68 -0
- package/app/modules/stickerPackModule/stickerPackEngagementRepository.js +152 -0
- package/app/modules/stickerPackModule/stickerPackErrors.js +30 -0
- package/app/modules/stickerPackModule/stickerPackInteractionEventRepository.js +101 -0
- package/app/modules/stickerPackModule/stickerPackItemRepository.js +432 -0
- package/app/modules/stickerPackModule/stickerPackMarketplaceService.js +313 -0
- package/app/modules/stickerPackModule/stickerPackMessageService.js +268 -0
- package/app/modules/stickerPackModule/stickerPackRepository.js +450 -0
- package/app/modules/stickerPackModule/stickerPackScoreSnapshotRepository.js +179 -0
- package/app/modules/stickerPackModule/stickerPackScoreSnapshotRuntime.js +271 -0
- package/app/modules/stickerPackModule/stickerPackService.js +733 -0
- package/app/modules/stickerPackModule/stickerPackServiceRuntime.js +32 -0
- package/app/modules/stickerPackModule/stickerPackUtils.js +107 -0
- package/app/modules/stickerPackModule/stickerStorageService.js +559 -0
- package/app/modules/stickerPackModule/stickerWorkerPipelineRuntime.js +242 -0
- package/app/modules/stickerPackModule/stickerWorkerTaskQueueRepository.js +242 -0
- package/app/modules/systemMetricsModule/AGENT.md +193 -0
- package/app/modules/systemMetricsModule/commandConfig.json +344 -0
- package/app/modules/systemMetricsModule/pingCommand.js +399 -0
- package/app/modules/systemMetricsModule/systemMetricsAiHelpService.js +14 -0
- package/app/modules/systemMetricsModule/systemMetricsConfigRuntime.js +68 -0
- package/app/modules/tiktokModule/AGENT.md +196 -0
- package/app/modules/tiktokModule/commandConfig.json +366 -0
- package/app/modules/tiktokModule/tiktokAiHelpService.js +14 -0
- package/app/modules/tiktokModule/tiktokCommand.js +716 -0
- package/app/modules/tiktokModule/tiktokConfigRuntime.js +68 -0
- package/app/modules/userModule/AGENT.md +200 -0
- package/app/modules/userModule/commandConfig.json +386 -0
- package/app/modules/userModule/userAiHelpService.js +14 -0
- package/app/modules/userModule/userCommand.js +1155 -0
- package/app/modules/userModule/userConfigRuntime.js +68 -0
- package/app/modules/waifuPicsModule/AGENT.md +431 -0
- package/app/modules/waifuPicsModule/commandConfig.json +780 -0
- package/app/modules/waifuPicsModule/waifuPicsAiHelpService.js +14 -0
- package/app/modules/waifuPicsModule/waifuPicsCommand.js +586 -0
- package/app/modules/waifuPicsModule/waifuPicsConfigRuntime.js +68 -0
- package/app/observability/metrics.js +766 -0
- package/app/services/ai/aiHelpResponseCacheRepository.js +280 -0
- package/app/services/ai/aiLearningRepository.js +400 -0
- package/app/services/ai/commandConfigEnrichmentRepository.js +769 -0
- package/app/services/ai/commandConfigEnrichmentService.js +452 -0
- package/app/services/ai/commandConfigValidationService.js +443 -0
- package/app/services/ai/commandToolBuilderService.js +192 -0
- package/app/services/ai/conversationRouterService.js +516 -0
- package/app/services/ai/geminiService.js +115 -0
- package/app/services/ai/geminiService.test.js +87 -0
- package/app/services/ai/globalModuleAiHelpService.js +1412 -0
- package/app/services/ai/globalToolCallingService.js +203 -0
- package/app/services/ai/messageCommandExecutionService.js +391 -0
- package/app/services/ai/moduleAiHelpCoreService.js +1099 -0
- package/app/services/ai/moduleAiHelpWrapperFactory.js +65 -0
- package/app/services/ai/moduleCommandConfigRuntimeService.js +113 -0
- package/app/services/ai/moduleToolExecutorService.js +464 -0
- package/app/services/ai/moduleToolRegistryService.js +178 -0
- package/app/services/ai/toolCandidateSelectorService.js +781 -0
- package/app/services/auth/googleWebLinkService.js +80 -0
- package/app/services/auth/whatsappLoginLinkService.js +230 -0
- package/app/services/external/pokeApiService.js +398 -0
- package/app/services/group/groupMetadataService.js +311 -0
- package/app/services/infra/dbWriteQueue.js +874 -0
- package/app/services/infra/featureFlagService.js +131 -0
- package/app/services/infra/queueUtils.js +55 -0
- package/app/services/messaging/captchaService.js +491 -0
- package/app/services/messaging/messagePersistenceService.js +1 -0
- package/app/services/messaging/newsBroadcastService.js +347 -0
- package/app/services/sticker/stickerFocusService.js +347 -0
- package/app/services/sticker/stickerFocusService.test.js +43 -0
- package/app/store/aiPromptStore.js +38 -0
- package/app/store/conversationSessionStore.js +131 -0
- package/app/store/groupConfigStore.js +58 -0
- package/app/store/premiumUserStore.js +54 -0
- package/app/utils/antiLink/antiLinkModule.js +700 -0
- package/app/utils/http/getImageBufferModule.js +18 -0
- package/app/utils/json/jsonSanitizer.js +113 -0
- package/app/utils/json/jsonSanitizer.test.js +40 -0
- package/app/utils/systemMetrics/systemMetricsModule.js +88 -0
- package/app/workers/aiLearningWorker.js +605 -0
- package/app/workers/commandConfigEnrichmentWorker.js +242 -0
- package/database/index.js +2075 -0
- package/database/init.js +151 -0
- package/database/migrations/.gitkeep +0 -0
- package/database/migrations/20260307_d0_hardening_down.sql +64 -0
- package/database/migrations/20260307_d0_hardening_up.sql +79 -0
- package/database/migrations/20260307_d1_terms_acceptance_down.sql +11 -0
- package/database/migrations/20260307_d1_terms_acceptance_up.sql +37 -0
- package/database/migrations/20260307_d2_auth_hardening_down.sql +75 -0
- package/database/migrations/20260307_d2_auth_hardening_up.sql +100 -0
- package/database/migrations/20260314_d7_canonical_sender_down.sql +53 -0
- package/database/migrations/20260314_d7_canonical_sender_up.sql +114 -0
- package/database/migrations/20260406_d30_security_analytics_down.sql +95 -0
- package/database/migrations/20260406_d30_security_analytics_up.sql +292 -0
- package/database/migrations/20260407_d31_web_google_session_token_hardening_down.sql +2 -0
- package/database/migrations/20260407_d31_web_google_session_token_hardening_up.sql +17 -0
- package/database/migrations/20260408_d32_ai_help_response_cache_down.sql +1 -0
- package/database/migrations/20260408_d32_ai_help_response_cache_up.sql +22 -0
- package/database/migrations/20260409_d33_ai_learning_tables_down.sql +4 -0
- package/database/migrations/20260409_d33_ai_learning_tables_up.sql +52 -0
- package/database/migrations/20260410_d34_command_config_enrichment_down.sql +3 -0
- package/database/migrations/20260410_d34_command_config_enrichment_up.sql +48 -0
- package/database/schema.sql +1186 -0
- package/docker-compose.yml +104 -0
- package/docs/audits/stickerCatalogController-out-of-scope.md +103 -0
- package/docs/audits/stickerCatalogController-symbols.md +58 -0
- package/docs/compliance/acceptable-use-policy-2026-03-07.md +35 -0
- package/docs/compliance/dpa-b2b-standard-2026-03-07.md +80 -0
- package/docs/compliance/monthly-compliance-checklist-2026-03-07.md +88 -0
- package/docs/compliance/notice-and-takedown-policy-2026-03-07.md +34 -0
- package/docs/compliance/privacy-policy-2026-03-07.md +75 -0
- package/docs/compliance/subprocessors-inventory-2026-03-07.md +16 -0
- package/docs/database/production-db-evolution-runbook-2026q1.md +365 -0
- package/docs/security/dsar-lgpd-runbook-2026-03-07.md +86 -0
- package/docs/security/incident-response-lgpd-anpd-runbook-2026-03-07.md +77 -0
- package/docs/security/network-hardening-runbook-2026-03-07.md +137 -0
- package/docs/seo/omnizap-seo-playbook-br-2026-02-28.md +238 -0
- package/docs/seo/satellite-page-template.md +116 -0
- package/docs/seo/satellite-pages-phase1.json +364 -0
- package/docs/wiki/Home.md +120 -0
- package/docs/wiki/pair-extraordinaire-2026-03-08.md +3 -0
- package/docs/wiki/recent-changes-2026-03-08.md +47 -0
- package/ecosystem.prod.config.cjs +135 -0
- package/eslint.config.js +89 -0
- package/index.js +488 -0
- package/ml/clip_classifier/Dockerfile +18 -0
- package/ml/clip_classifier/README.md +118 -0
- package/ml/clip_classifier/adaptive_scoring.py +40 -0
- package/ml/clip_classifier/classifier.py +654 -0
- package/ml/clip_classifier/embedding_store.py +481 -0
- package/ml/clip_classifier/env_loader.py +15 -0
- package/ml/clip_classifier/llm_label_expander.py +144 -0
- package/ml/clip_classifier/main.py +213 -0
- package/ml/clip_classifier/requirements.txt +10 -0
- package/ml/clip_classifier/similarity_engine.py +74 -0
- package/new-logo.png +0 -0
- package/observability/alert-rules.yml +60 -0
- package/observability/grafana/dashboards/omnizap-mysql.json +136 -0
- package/observability/grafana/dashboards/omnizap-overview.json +170 -0
- package/observability/grafana/provisioning/dashboards/dashboards.yml +11 -0
- package/observability/grafana/provisioning/datasources/datasources.yml +15 -0
- package/observability/loki-config.yml +38 -0
- package/observability/mysql-setup.sql +46 -0
- package/observability/prometheus.yml +35 -0
- package/observability/promtail-config.yml +84 -0
- package/observability/sticker-catalog-slo.md +83 -0
- package/observability/sticker-scale-hardening-rollout.md +128 -0
- package/package.json +144 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/assets/css/commands-react.input.css +71 -0
- package/public/assets/css/create-pack-react.input.css +31 -0
- package/public/assets/css/home-react.input.css +106 -0
- package/public/assets/css/login-react.input.css +58 -0
- package/public/assets/css/stickers-react.input.css +18 -0
- package/public/assets/css/terms-react.input.css +115 -0
- package/public/assets/css/user-react.input.css +57 -0
- package/public/assets/images/brand-icon-192.png +0 -0
- package/public/assets/images/brand-logo-128.webp +0 -0
- package/public/assets/images/hero-banner-1280.jpg +0 -0
- package/public/comandos/commands-catalog.json +4517 -0
- package/public/css/api-docs.css +161 -0
- package/public/css/stickers-admin.css +1288 -0
- package/public/css/styles.css +679 -0
- package/public/css/systemadm/admin.css +474 -0
- package/public/css/systemadm/base.css +73 -0
- package/public/css/systemadm/components.css +662 -0
- package/public/css/systemadm/layout.css +229 -0
- package/public/css/systemadm/tokens.css +56 -0
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/js/apps/apiDocsApp.js +235 -0
- package/public/js/apps/commandsReactApp.js +528 -0
- package/public/js/apps/createPackApp.js +1646 -0
- package/public/js/apps/homeReactApp.js +942 -0
- package/public/js/apps/loginReactApp.js +496 -0
- package/public/js/apps/stickersAdminApp.js +1753 -0
- package/public/js/apps/stickersApp.js +3797 -0
- package/public/js/apps/termsReactApp.js +528 -0
- package/public/js/apps/userApp.js +2540 -0
- package/public/js/apps/userProfile/actions.js +66 -0
- package/public/js/apps/userReactApp.js +547 -0
- package/public/js/catalog.js +950 -0
- package/public/pages/api-docs.html +40 -0
- package/public/pages/aup.html +158 -0
- package/public/pages/comandos.html +41 -0
- package/public/pages/dpa.html +227 -0
- package/public/pages/home.html +45 -0
- package/public/pages/licenca.html +182 -0
- package/public/pages/login.html +40 -0
- package/public/pages/notice-and-takedown.html +234 -0
- package/public/pages/politica-de-privacidade.html +251 -0
- package/public/pages/seo-bot-whatsapp-para-grupo.html +350 -0
- package/public/pages/seo-bot-whatsapp-sem-programar.html +350 -0
- package/public/pages/seo-como-automatizar-avisos-no-whatsapp.html +350 -0
- package/public/pages/seo-como-criar-comandos-whatsapp.html +350 -0
- package/public/pages/seo-como-evitar-spam-no-whatsapp.html +350 -0
- package/public/pages/seo-como-moderar-grupo-whatsapp.html +350 -0
- package/public/pages/seo-como-organizar-comunidade-whatsapp.html +350 -0
- package/public/pages/seo-melhor-bot-whatsapp-para-grupos.html +350 -0
- package/public/pages/stickers-admin.html +31 -0
- package/public/pages/stickers-create.html +41 -0
- package/public/pages/stickers.html +45 -0
- package/public/pages/suboperadores.html +237 -0
- package/public/pages/termos-de-uso-texto-integral.html +241 -0
- package/public/pages/termos-de-uso.html +41 -0
- package/public/pages/user-password-reset.html +32 -0
- package/public/pages/user-systemadm.html +508 -0
- package/public/pages/user.html +39 -0
- package/public/robots.txt +9 -0
- package/public/site.webmanifest +24 -0
- package/public/sitemap.xml +98 -0
- package/schemas/command-config.schema.json +582 -0
- package/scripts/baileys-compat-smoke.mjs +12 -0
- package/scripts/cache-bust.mjs +142 -0
- package/scripts/deploy.sh +916 -0
- package/scripts/email-broadcast-terms-update.mjs +170 -0
- package/scripts/enrich-command-discovery-fields.mjs +286 -0
- package/scripts/generate-command-config-schema.mjs +273 -0
- package/scripts/generate-commands-catalog.mjs +308 -0
- package/scripts/generate-module-agents.mjs +631 -0
- package/scripts/generate-seo-satellite-pages.mjs +400 -0
- package/scripts/github-deploy-notify.mjs +174 -0
- package/scripts/github-release-notify.mjs +219 -0
- package/scripts/release.sh +599 -0
- package/scripts/run-codeql-local.sh +116 -0
- package/scripts/run-prettier-all.mjs +25 -0
- package/scripts/security-smoketest.mjs +581 -0
- package/scripts/sticker-catalog-loadtest.mjs +210 -0
- package/scripts/sticker-worker-task.mjs +119 -0
- package/scripts/sync-readme-snapshot.mjs +133 -0
- package/scripts/validate-command-config-schema.mjs +130 -0
- package/scripts/validate-command-configs.mjs +15 -0
- package/scripts/wiki-sync.sh +191 -0
- package/server/auth/googleWebAuth/googleWebAuthRuntime.js +62 -0
- package/server/auth/googleWebAuth/googleWebAuthService.js +807 -0
- package/server/auth/jwt/webJwtService.js +147 -0
- package/server/auth/stickerCatalogAuthContext.js +165 -0
- package/server/auth/termsAcceptance/termsAcceptanceHandler.js +189 -0
- package/server/auth/userPassword/index.js +14 -0
- package/server/auth/userPassword/userPasswordAuthService.js +422 -0
- package/server/auth/userPassword/userPasswordCrypto.js +199 -0
- package/server/auth/userPassword/userPasswordCrypto.test.js +76 -0
- package/server/auth/userPassword/userPasswordRecoveryService.js +728 -0
- package/server/auth/validation/authSchemas.js +236 -0
- package/server/auth/webAccount/webAccountHandlers.js +1434 -0
- package/server/controllers/admin/adminBanService.js +138 -0
- package/server/controllers/admin/adminPanelHandlers.js +2083 -0
- package/server/controllers/admin/stickerCatalogAdminContext.js +17 -0
- package/server/controllers/admin/systemAdminController.js +201 -0
- package/server/controllers/email/emailAutomationController.js +239 -0
- package/server/controllers/metricsController.js +21 -0
- package/server/controllers/seo/stickerCatalogSeoContext.js +514 -0
- package/server/controllers/sticker/nonCatalogHandlers.js +303 -0
- package/server/controllers/sticker/stickerCatalogController.js +4700 -0
- package/server/controllers/system/contactController.js +115 -0
- package/server/controllers/system/githubController.js +137 -0
- package/server/controllers/system/stickerCatalogSystemContext.js +758 -0
- package/server/controllers/system/storageController.js +154 -0
- package/server/controllers/system/systemController.js +135 -0
- package/server/controllers/system/systemMetricsController.js +156 -0
- package/server/controllers/system/visitController.js +90 -0
- package/server/controllers/userController.js +145 -0
- package/server/email/emailAutomationRuntime.js +225 -0
- package/server/email/emailAutomationService.js +125 -0
- package/server/email/emailOutboxRepository.js +282 -0
- package/server/email/emailTemplateService.js +480 -0
- package/server/email/emailTransportService.js +156 -0
- package/server/http/clientIp.js +95 -0
- package/server/http/httpRequestUtils.js +262 -0
- package/server/http/httpRequestUtils.test.js +80 -0
- package/server/http/httpServer.js +180 -0
- package/server/http/requestContext.js +20 -0
- package/server/http/siteRoutingUtils.js +87 -0
- package/server/index.js +1 -0
- package/server/middleware/cachePolicy.js +26 -0
- package/server/middleware/cachePolicyHelpers.js +1 -0
- package/server/middleware/endpointRateLimit.js +181 -0
- package/server/middleware/rateLimit.js +70 -0
- package/server/middleware/requireAdminAuth.js +48 -0
- package/server/middleware/securityHeaders.js +97 -0
- package/server/routes/admin/systemAdminRouter.js +64 -0
- package/server/routes/email/emailAutomationRouter.js +46 -0
- package/server/routes/health/healthRouter.js +41 -0
- package/server/routes/indexRouter.js +234 -0
- package/server/routes/metrics/metricsRouter.js +58 -0
- package/server/routes/static/staticPageRouter.js +134 -0
- package/server/routes/sticker/catalogHandlers/catalogAdminHttp.js +105 -0
- package/server/routes/sticker/catalogHandlers/catalogAuthHttp.js +77 -0
- package/server/routes/sticker/catalogHandlers/catalogPublicHttp.js +120 -0
- package/server/routes/sticker/catalogHandlers/catalogUploadHttp.js +83 -0
- package/server/routes/sticker/catalogRouter.js +77 -0
- package/server/routes/sticker/stickerApiRouter.js +84 -0
- package/server/routes/sticker/stickerDataRouter.js +145 -0
- package/server/routes/sticker/stickerSiteRouter.js +43 -0
- package/server/routes/user/userApiPaths.js +66 -0
- package/server/routes/user/userRouter.js +65 -0
- package/server/utils/safePath.js +26 -0
- package/utils/logger/loggerModule.js +35 -0
- package/vite.config.mjs +38 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
-- D+30 rollback
|
|
2
|
+
|
|
3
|
+
SET @migration_key := '20260406_d30_security_analytics';
|
|
4
|
+
|
|
5
|
+
DROP EVENT IF EXISTS ev_rollup_message_activity_daily;
|
|
6
|
+
DROP EVENT IF EXISTS ev_purge_baileys_event_journal;
|
|
7
|
+
DROP EVENT IF EXISTS ev_purge_message_analysis_event;
|
|
8
|
+
DROP EVENT IF EXISTS ev_purge_web_visit_event;
|
|
9
|
+
DROP EVENT IF EXISTS ev_purge_sticker_pack_interaction_event;
|
|
10
|
+
|
|
11
|
+
DROP PROCEDURE IF EXISTS __drop_check_if_exists;
|
|
12
|
+
DROP PROCEDURE IF EXISTS __drop_index_if_exists;
|
|
13
|
+
DROP PROCEDURE IF EXISTS __drop_column_if_exists;
|
|
14
|
+
|
|
15
|
+
DELIMITER $$
|
|
16
|
+
CREATE PROCEDURE __drop_check_if_exists(IN p_table_name VARCHAR(64), IN p_constraint_name VARCHAR(128))
|
|
17
|
+
BEGIN
|
|
18
|
+
DECLARE v_is_mariadb TINYINT DEFAULT 0;
|
|
19
|
+
|
|
20
|
+
SET v_is_mariadb = IF(VERSION() LIKE '%MariaDB%', 1, 0);
|
|
21
|
+
|
|
22
|
+
IF EXISTS (
|
|
23
|
+
SELECT 1
|
|
24
|
+
FROM information_schema.table_constraints
|
|
25
|
+
WHERE table_schema = DATABASE()
|
|
26
|
+
AND table_name = p_table_name
|
|
27
|
+
AND constraint_name = p_constraint_name
|
|
28
|
+
AND constraint_type = 'CHECK'
|
|
29
|
+
) THEN
|
|
30
|
+
IF v_is_mariadb = 1 THEN
|
|
31
|
+
SET @ddl = CONCAT('ALTER TABLE `', p_table_name, '` DROP CONSTRAINT `', p_constraint_name, '`');
|
|
32
|
+
ELSE
|
|
33
|
+
SET @ddl = CONCAT('ALTER TABLE `', p_table_name, '` DROP CHECK `', p_constraint_name, '`');
|
|
34
|
+
END IF;
|
|
35
|
+
PREPARE stmt FROM @ddl;
|
|
36
|
+
EXECUTE stmt;
|
|
37
|
+
DEALLOCATE PREPARE stmt;
|
|
38
|
+
END IF;
|
|
39
|
+
END$$
|
|
40
|
+
|
|
41
|
+
CREATE PROCEDURE __drop_index_if_exists(IN p_table_name VARCHAR(64), IN p_index_name VARCHAR(64))
|
|
42
|
+
BEGIN
|
|
43
|
+
IF EXISTS (
|
|
44
|
+
SELECT 1
|
|
45
|
+
FROM information_schema.statistics
|
|
46
|
+
WHERE table_schema = DATABASE()
|
|
47
|
+
AND table_name = p_table_name
|
|
48
|
+
AND index_name = p_index_name
|
|
49
|
+
) THEN
|
|
50
|
+
SET @ddl = CONCAT('ALTER TABLE `', p_table_name, '` DROP INDEX `', p_index_name, '`');
|
|
51
|
+
PREPARE stmt FROM @ddl;
|
|
52
|
+
EXECUTE stmt;
|
|
53
|
+
DEALLOCATE PREPARE stmt;
|
|
54
|
+
END IF;
|
|
55
|
+
END$$
|
|
56
|
+
|
|
57
|
+
CREATE PROCEDURE __drop_column_if_exists(IN p_table_name VARCHAR(64), IN p_column_name VARCHAR(64))
|
|
58
|
+
BEGIN
|
|
59
|
+
IF EXISTS (
|
|
60
|
+
SELECT 1
|
|
61
|
+
FROM information_schema.columns
|
|
62
|
+
WHERE table_schema = DATABASE()
|
|
63
|
+
AND table_name = p_table_name
|
|
64
|
+
AND column_name = p_column_name
|
|
65
|
+
) THEN
|
|
66
|
+
SET @ddl = CONCAT('ALTER TABLE `', p_table_name, '` DROP COLUMN `', p_column_name, '`');
|
|
67
|
+
PREPARE stmt FROM @ddl;
|
|
68
|
+
EXECUTE stmt;
|
|
69
|
+
DEALLOCATE PREPARE stmt;
|
|
70
|
+
END IF;
|
|
71
|
+
END$$
|
|
72
|
+
DELIMITER ;
|
|
73
|
+
|
|
74
|
+
CALL __drop_check_if_exists('feature_flag', 'chk_feature_flag_rollout_percent');
|
|
75
|
+
CALL __drop_check_if_exists('domain_event_outbox', 'chk_domain_event_outbox_attempts');
|
|
76
|
+
CALL __drop_check_if_exists('email_outbox', 'chk_email_outbox_attempts');
|
|
77
|
+
CALL __drop_check_if_exists('sticker_worker_task_queue', 'chk_sticker_worker_task_queue_attempts');
|
|
78
|
+
CALL __drop_check_if_exists('sticker_asset_reprocess_queue', 'chk_sticker_asset_reprocess_queue_attempts');
|
|
79
|
+
CALL __drop_check_if_exists('rpg_karma_vote_history', 'chk_rpg_karma_vote_value');
|
|
80
|
+
CALL __drop_check_if_exists('rpg_social_link', 'chk_rpg_social_link_distinct_users');
|
|
81
|
+
|
|
82
|
+
DROP TABLE IF EXISTS message_activity_daily;
|
|
83
|
+
|
|
84
|
+
CALL __drop_index_if_exists('web_google_session', 'uq_web_google_session_token_hash');
|
|
85
|
+
CALL __drop_column_if_exists('web_google_session', 'session_token_hash');
|
|
86
|
+
|
|
87
|
+
UPDATE schema_change_log
|
|
88
|
+
SET status = 'rolled_back',
|
|
89
|
+
notes = 'D+30 rollback executed',
|
|
90
|
+
updated_at = CURRENT_TIMESTAMP
|
|
91
|
+
WHERE migration_key = @migration_key;
|
|
92
|
+
|
|
93
|
+
DROP PROCEDURE IF EXISTS __drop_check_if_exists;
|
|
94
|
+
DROP PROCEDURE IF EXISTS __drop_index_if_exists;
|
|
95
|
+
DROP PROCEDURE IF EXISTS __drop_column_if_exists;
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
-- D+30 (2026-04-06) - Larger migration
|
|
2
|
+
-- Scope: auth session hardening, daily aggregate table, data-retention events, consistency checks
|
|
3
|
+
|
|
4
|
+
SET @migration_key := '20260406_d30_security_analytics';
|
|
5
|
+
|
|
6
|
+
DROP PROCEDURE IF EXISTS __ensure_column;
|
|
7
|
+
DROP PROCEDURE IF EXISTS __ensure_index;
|
|
8
|
+
DROP PROCEDURE IF EXISTS __exec_when;
|
|
9
|
+
|
|
10
|
+
DELIMITER $$
|
|
11
|
+
CREATE PROCEDURE __ensure_column(IN p_table_name VARCHAR(64), IN p_column_name VARCHAR(64), IN p_ddl TEXT)
|
|
12
|
+
BEGIN
|
|
13
|
+
IF NOT EXISTS (
|
|
14
|
+
SELECT 1
|
|
15
|
+
FROM information_schema.columns
|
|
16
|
+
WHERE table_schema = DATABASE()
|
|
17
|
+
AND table_name = p_table_name
|
|
18
|
+
AND column_name = p_column_name
|
|
19
|
+
) THEN
|
|
20
|
+
SET @ddl = p_ddl;
|
|
21
|
+
PREPARE stmt FROM @ddl;
|
|
22
|
+
EXECUTE stmt;
|
|
23
|
+
DEALLOCATE PREPARE stmt;
|
|
24
|
+
END IF;
|
|
25
|
+
END$$
|
|
26
|
+
|
|
27
|
+
CREATE PROCEDURE __ensure_index(IN p_table_name VARCHAR(64), IN p_index_name VARCHAR(64), IN p_ddl TEXT)
|
|
28
|
+
BEGIN
|
|
29
|
+
IF NOT EXISTS (
|
|
30
|
+
SELECT 1
|
|
31
|
+
FROM information_schema.statistics
|
|
32
|
+
WHERE table_schema = DATABASE()
|
|
33
|
+
AND table_name = p_table_name
|
|
34
|
+
AND index_name = p_index_name
|
|
35
|
+
) THEN
|
|
36
|
+
SET @ddl = p_ddl;
|
|
37
|
+
PREPARE stmt FROM @ddl;
|
|
38
|
+
EXECUTE stmt;
|
|
39
|
+
DEALLOCATE PREPARE stmt;
|
|
40
|
+
END IF;
|
|
41
|
+
END$$
|
|
42
|
+
|
|
43
|
+
CREATE PROCEDURE __exec_when(IN p_condition BOOLEAN, IN p_ddl TEXT, IN p_skip_message VARCHAR(255))
|
|
44
|
+
BEGIN
|
|
45
|
+
IF p_condition THEN
|
|
46
|
+
SET @ddl = p_ddl;
|
|
47
|
+
PREPARE stmt FROM @ddl;
|
|
48
|
+
EXECUTE stmt;
|
|
49
|
+
DEALLOCATE PREPARE stmt;
|
|
50
|
+
ELSE
|
|
51
|
+
SELECT CONCAT('SKIPPED: ', p_skip_message) AS info_message;
|
|
52
|
+
END IF;
|
|
53
|
+
END$$
|
|
54
|
+
DELIMITER ;
|
|
55
|
+
|
|
56
|
+
-- 1) Session token hardening (backward-compatible)
|
|
57
|
+
CALL __ensure_column('web_google_session', 'session_token_hash', 'ALTER TABLE web_google_session ADD COLUMN session_token_hash BINARY(32) NULL AFTER session_token');
|
|
58
|
+
|
|
59
|
+
UPDATE web_google_session
|
|
60
|
+
SET session_token_hash = UNHEX(SHA2(session_token, 256))
|
|
61
|
+
WHERE session_token_hash IS NULL
|
|
62
|
+
AND session_token IS NOT NULL;
|
|
63
|
+
|
|
64
|
+
CALL __ensure_index('web_google_session', 'uq_web_google_session_token_hash', 'CREATE UNIQUE INDEX uq_web_google_session_token_hash ON web_google_session (session_token_hash)');
|
|
65
|
+
|
|
66
|
+
-- 2) Daily aggregate table for ranking/analytics
|
|
67
|
+
CREATE TABLE IF NOT EXISTS message_activity_daily (
|
|
68
|
+
day_ref_date DATE NOT NULL,
|
|
69
|
+
chat_id VARCHAR(255) NOT NULL,
|
|
70
|
+
canonical_sender_id VARCHAR(255) NOT NULL,
|
|
71
|
+
total_messages INT UNSIGNED NOT NULL DEFAULT 0,
|
|
72
|
+
first_message_at DATETIME DEFAULT NULL,
|
|
73
|
+
last_message_at DATETIME DEFAULT NULL,
|
|
74
|
+
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
75
|
+
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
76
|
+
PRIMARY KEY (day_ref_date, chat_id, canonical_sender_id),
|
|
77
|
+
KEY idx_message_activity_daily_sender_day (canonical_sender_id, day_ref_date),
|
|
78
|
+
KEY idx_message_activity_daily_chat_day (chat_id, day_ref_date)
|
|
79
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
80
|
+
|
|
81
|
+
-- Initial rebuild for last 90 days (adjust as needed)
|
|
82
|
+
DELETE FROM message_activity_daily
|
|
83
|
+
WHERE day_ref_date >= CURRENT_DATE - INTERVAL 90 DAY;
|
|
84
|
+
|
|
85
|
+
INSERT INTO message_activity_daily (
|
|
86
|
+
day_ref_date,
|
|
87
|
+
chat_id,
|
|
88
|
+
canonical_sender_id,
|
|
89
|
+
total_messages,
|
|
90
|
+
first_message_at,
|
|
91
|
+
last_message_at
|
|
92
|
+
)
|
|
93
|
+
SELECT
|
|
94
|
+
DATE(m.timestamp) AS day_ref_date,
|
|
95
|
+
m.chat_id,
|
|
96
|
+
COALESCE(m.canonical_sender_id, lm.jid, m.sender_id) AS canonical_sender_id,
|
|
97
|
+
COUNT(*) AS total_messages,
|
|
98
|
+
MIN(m.timestamp) AS first_message_at,
|
|
99
|
+
MAX(m.timestamp) AS last_message_at
|
|
100
|
+
FROM messages m
|
|
101
|
+
LEFT JOIN lid_map lm
|
|
102
|
+
ON lm.lid = m.sender_id
|
|
103
|
+
AND lm.jid IS NOT NULL
|
|
104
|
+
WHERE m.timestamp >= CURRENT_DATE - INTERVAL 90 DAY
|
|
105
|
+
AND m.timestamp IS NOT NULL
|
|
106
|
+
AND m.chat_id IS NOT NULL
|
|
107
|
+
AND COALESCE(m.canonical_sender_id, lm.jid, m.sender_id) IS NOT NULL
|
|
108
|
+
GROUP BY DATE(m.timestamp), m.chat_id, COALESCE(m.canonical_sender_id, lm.jid, m.sender_id)
|
|
109
|
+
ON DUPLICATE KEY UPDATE
|
|
110
|
+
total_messages = VALUES(total_messages),
|
|
111
|
+
first_message_at = VALUES(first_message_at),
|
|
112
|
+
last_message_at = VALUES(last_message_at),
|
|
113
|
+
updated_at = CURRENT_TIMESTAMP;
|
|
114
|
+
|
|
115
|
+
-- 3) Consistency checks (applies only when data is already clean)
|
|
116
|
+
SET @exists := (
|
|
117
|
+
SELECT COUNT(*)
|
|
118
|
+
FROM information_schema.table_constraints
|
|
119
|
+
WHERE table_schema = DATABASE()
|
|
120
|
+
AND table_name = 'feature_flag'
|
|
121
|
+
AND constraint_name = 'chk_feature_flag_rollout_percent'
|
|
122
|
+
);
|
|
123
|
+
SET @bad := (SELECT COUNT(*) FROM feature_flag WHERE rollout_percent < 0 OR rollout_percent > 100);
|
|
124
|
+
CALL __exec_when(@exists = 0 AND @bad = 0,
|
|
125
|
+
'ALTER TABLE feature_flag ADD CONSTRAINT chk_feature_flag_rollout_percent CHECK (rollout_percent BETWEEN 0 AND 100)',
|
|
126
|
+
'feature_flag rollout check not applied');
|
|
127
|
+
|
|
128
|
+
SET @exists := (
|
|
129
|
+
SELECT COUNT(*)
|
|
130
|
+
FROM information_schema.table_constraints
|
|
131
|
+
WHERE table_schema = DATABASE()
|
|
132
|
+
AND table_name = 'domain_event_outbox'
|
|
133
|
+
AND constraint_name = 'chk_domain_event_outbox_attempts'
|
|
134
|
+
);
|
|
135
|
+
SET @bad := (SELECT COUNT(*) FROM domain_event_outbox WHERE attempts > max_attempts);
|
|
136
|
+
CALL __exec_when(@exists = 0 AND @bad = 0,
|
|
137
|
+
'ALTER TABLE domain_event_outbox ADD CONSTRAINT chk_domain_event_outbox_attempts CHECK (attempts <= max_attempts)',
|
|
138
|
+
'domain_event_outbox attempts check not applied');
|
|
139
|
+
|
|
140
|
+
SET @exists := (
|
|
141
|
+
SELECT COUNT(*)
|
|
142
|
+
FROM information_schema.table_constraints
|
|
143
|
+
WHERE table_schema = DATABASE()
|
|
144
|
+
AND table_name = 'email_outbox'
|
|
145
|
+
AND constraint_name = 'chk_email_outbox_attempts'
|
|
146
|
+
);
|
|
147
|
+
SET @bad := (SELECT COUNT(*) FROM email_outbox WHERE attempts > max_attempts);
|
|
148
|
+
CALL __exec_when(@exists = 0 AND @bad = 0,
|
|
149
|
+
'ALTER TABLE email_outbox ADD CONSTRAINT chk_email_outbox_attempts CHECK (attempts <= max_attempts)',
|
|
150
|
+
'email_outbox attempts check not applied');
|
|
151
|
+
|
|
152
|
+
SET @exists := (
|
|
153
|
+
SELECT COUNT(*)
|
|
154
|
+
FROM information_schema.table_constraints
|
|
155
|
+
WHERE table_schema = DATABASE()
|
|
156
|
+
AND table_name = 'sticker_worker_task_queue'
|
|
157
|
+
AND constraint_name = 'chk_sticker_worker_task_queue_attempts'
|
|
158
|
+
);
|
|
159
|
+
SET @bad := (SELECT COUNT(*) FROM sticker_worker_task_queue WHERE attempts > max_attempts);
|
|
160
|
+
CALL __exec_when(@exists = 0 AND @bad = 0,
|
|
161
|
+
'ALTER TABLE sticker_worker_task_queue ADD CONSTRAINT chk_sticker_worker_task_queue_attempts CHECK (attempts <= max_attempts)',
|
|
162
|
+
'sticker_worker_task_queue attempts check not applied');
|
|
163
|
+
|
|
164
|
+
SET @exists := (
|
|
165
|
+
SELECT COUNT(*)
|
|
166
|
+
FROM information_schema.table_constraints
|
|
167
|
+
WHERE table_schema = DATABASE()
|
|
168
|
+
AND table_name = 'sticker_asset_reprocess_queue'
|
|
169
|
+
AND constraint_name = 'chk_sticker_asset_reprocess_queue_attempts'
|
|
170
|
+
);
|
|
171
|
+
SET @bad := (SELECT COUNT(*) FROM sticker_asset_reprocess_queue WHERE attempts > max_attempts);
|
|
172
|
+
CALL __exec_when(@exists = 0 AND @bad = 0,
|
|
173
|
+
'ALTER TABLE sticker_asset_reprocess_queue ADD CONSTRAINT chk_sticker_asset_reprocess_queue_attempts CHECK (attempts <= max_attempts)',
|
|
174
|
+
'sticker_asset_reprocess_queue attempts check not applied');
|
|
175
|
+
|
|
176
|
+
SET @exists := (
|
|
177
|
+
SELECT COUNT(*)
|
|
178
|
+
FROM information_schema.table_constraints
|
|
179
|
+
WHERE table_schema = DATABASE()
|
|
180
|
+
AND table_name = 'rpg_karma_vote_history'
|
|
181
|
+
AND constraint_name = 'chk_rpg_karma_vote_value'
|
|
182
|
+
);
|
|
183
|
+
SET @bad := (SELECT COUNT(*) FROM rpg_karma_vote_history WHERE vote_value NOT IN (-1, 1));
|
|
184
|
+
CALL __exec_when(@exists = 0 AND @bad = 0,
|
|
185
|
+
'ALTER TABLE rpg_karma_vote_history ADD CONSTRAINT chk_rpg_karma_vote_value CHECK (vote_value IN (-1, 1))',
|
|
186
|
+
'rpg_karma_vote_history vote check not applied');
|
|
187
|
+
|
|
188
|
+
SET @exists := (
|
|
189
|
+
SELECT COUNT(*)
|
|
190
|
+
FROM information_schema.table_constraints
|
|
191
|
+
WHERE table_schema = DATABASE()
|
|
192
|
+
AND table_name = 'rpg_social_link'
|
|
193
|
+
AND constraint_name = 'chk_rpg_social_link_distinct_users'
|
|
194
|
+
);
|
|
195
|
+
SET @bad := (SELECT COUNT(*) FROM rpg_social_link WHERE user_a_jid = user_b_jid);
|
|
196
|
+
SET @is_mariadb := (SELECT IF(VERSION() LIKE '%MariaDB%', 1, 0));
|
|
197
|
+
SET @has_fk_referential_actions := (
|
|
198
|
+
SELECT COUNT(*)
|
|
199
|
+
FROM information_schema.key_column_usage kcu
|
|
200
|
+
JOIN information_schema.referential_constraints rc
|
|
201
|
+
ON rc.constraint_schema = kcu.constraint_schema
|
|
202
|
+
AND rc.table_name = kcu.table_name
|
|
203
|
+
AND rc.constraint_name = kcu.constraint_name
|
|
204
|
+
WHERE kcu.table_schema = DATABASE()
|
|
205
|
+
AND kcu.table_name = 'rpg_social_link'
|
|
206
|
+
AND kcu.column_name IN ('user_a_jid', 'user_b_jid')
|
|
207
|
+
AND (
|
|
208
|
+
rc.update_rule NOT IN ('RESTRICT', 'NO ACTION')
|
|
209
|
+
OR rc.delete_rule NOT IN ('RESTRICT', 'NO ACTION')
|
|
210
|
+
)
|
|
211
|
+
);
|
|
212
|
+
CALL __exec_when(@exists = 0 AND @bad = 0 AND @is_mariadb = 0 AND @has_fk_referential_actions = 0,
|
|
213
|
+
'ALTER TABLE rpg_social_link ADD CONSTRAINT chk_rpg_social_link_distinct_users CHECK (user_a_jid <> user_b_jid)',
|
|
214
|
+
'rpg_social_link distinct user check not applied (MariaDB/FK actions compatibility or dirty data)');
|
|
215
|
+
|
|
216
|
+
-- 4) Automatic rollup and retention events
|
|
217
|
+
-- Note: requires EVENT_SCHEDULER=ON at server level.
|
|
218
|
+
|
|
219
|
+
CREATE EVENT IF NOT EXISTS ev_rollup_message_activity_daily
|
|
220
|
+
ON SCHEDULE EVERY 1 DAY
|
|
221
|
+
STARTS (CURRENT_DATE + INTERVAL 1 DAY + INTERVAL 5 MINUTE)
|
|
222
|
+
DO
|
|
223
|
+
INSERT INTO message_activity_daily (
|
|
224
|
+
day_ref_date,
|
|
225
|
+
chat_id,
|
|
226
|
+
canonical_sender_id,
|
|
227
|
+
total_messages,
|
|
228
|
+
first_message_at,
|
|
229
|
+
last_message_at
|
|
230
|
+
)
|
|
231
|
+
SELECT
|
|
232
|
+
DATE(m.timestamp) AS day_ref_date,
|
|
233
|
+
m.chat_id,
|
|
234
|
+
COALESCE(m.canonical_sender_id, lm.jid, m.sender_id) AS canonical_sender_id,
|
|
235
|
+
COUNT(*) AS total_messages,
|
|
236
|
+
MIN(m.timestamp) AS first_message_at,
|
|
237
|
+
MAX(m.timestamp) AS last_message_at
|
|
238
|
+
FROM messages m
|
|
239
|
+
LEFT JOIN lid_map lm
|
|
240
|
+
ON lm.lid = m.sender_id
|
|
241
|
+
AND lm.jid IS NOT NULL
|
|
242
|
+
WHERE m.timestamp >= CURRENT_DATE - INTERVAL 2 DAY
|
|
243
|
+
AND m.timestamp < CURRENT_DATE + INTERVAL 1 DAY
|
|
244
|
+
AND m.timestamp IS NOT NULL
|
|
245
|
+
AND m.chat_id IS NOT NULL
|
|
246
|
+
AND COALESCE(m.canonical_sender_id, lm.jid, m.sender_id) IS NOT NULL
|
|
247
|
+
GROUP BY DATE(m.timestamp), m.chat_id, COALESCE(m.canonical_sender_id, lm.jid, m.sender_id)
|
|
248
|
+
ON DUPLICATE KEY UPDATE
|
|
249
|
+
total_messages = VALUES(total_messages),
|
|
250
|
+
first_message_at = VALUES(first_message_at),
|
|
251
|
+
last_message_at = VALUES(last_message_at),
|
|
252
|
+
updated_at = CURRENT_TIMESTAMP;
|
|
253
|
+
|
|
254
|
+
CREATE EVENT IF NOT EXISTS ev_purge_baileys_event_journal
|
|
255
|
+
ON SCHEDULE EVERY 1 DAY
|
|
256
|
+
DO
|
|
257
|
+
DELETE FROM baileys_event_journal
|
|
258
|
+
WHERE created_at < NOW() - INTERVAL 30 DAY
|
|
259
|
+
LIMIT 50000;
|
|
260
|
+
|
|
261
|
+
CREATE EVENT IF NOT EXISTS ev_purge_message_analysis_event
|
|
262
|
+
ON SCHEDULE EVERY 1 DAY
|
|
263
|
+
DO
|
|
264
|
+
DELETE FROM message_analysis_event
|
|
265
|
+
WHERE created_at < NOW() - INTERVAL 90 DAY
|
|
266
|
+
LIMIT 50000;
|
|
267
|
+
|
|
268
|
+
CREATE EVENT IF NOT EXISTS ev_purge_web_visit_event
|
|
269
|
+
ON SCHEDULE EVERY 1 DAY
|
|
270
|
+
DO
|
|
271
|
+
DELETE FROM web_visit_event
|
|
272
|
+
WHERE created_at < NOW() - INTERVAL 120 DAY
|
|
273
|
+
LIMIT 100000;
|
|
274
|
+
|
|
275
|
+
CREATE EVENT IF NOT EXISTS ev_purge_sticker_pack_interaction_event
|
|
276
|
+
ON SCHEDULE EVERY 1 DAY
|
|
277
|
+
DO
|
|
278
|
+
DELETE FROM sticker_pack_interaction_event
|
|
279
|
+
WHERE created_at < NOW() - INTERVAL 180 DAY
|
|
280
|
+
LIMIT 100000;
|
|
281
|
+
|
|
282
|
+
INSERT INTO schema_change_log (migration_key, phase, status, notes)
|
|
283
|
+
VALUES (@migration_key, 'D+30', 'applied', 'session hash + daily aggregate + checks + retention events')
|
|
284
|
+
ON DUPLICATE KEY UPDATE
|
|
285
|
+
phase = VALUES(phase),
|
|
286
|
+
status = 'applied',
|
|
287
|
+
notes = VALUES(notes),
|
|
288
|
+
updated_at = CURRENT_TIMESTAMP;
|
|
289
|
+
|
|
290
|
+
DROP PROCEDURE IF EXISTS __ensure_column;
|
|
291
|
+
DROP PROCEDURE IF EXISTS __ensure_index;
|
|
292
|
+
DROP PROCEDURE IF EXISTS __exec_when;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
-- Harden `web_google_session` token persistence:
|
|
2
|
+
-- 1) guarantee hash is present for every row
|
|
3
|
+
-- 2) ensure `session_token` stores only a non-sensitive deterministic row key
|
|
4
|
+
-- 3) enforce NOT NULL on `session_token_hash`
|
|
5
|
+
|
|
6
|
+
UPDATE web_google_session
|
|
7
|
+
SET session_token_hash = UNHEX(SHA2(session_token, 256))
|
|
8
|
+
WHERE session_token_hash IS NULL
|
|
9
|
+
AND session_token IS NOT NULL;
|
|
10
|
+
|
|
11
|
+
UPDATE web_google_session
|
|
12
|
+
SET session_token = LOWER(SUBSTRING(HEX(session_token_hash), 1, 36))
|
|
13
|
+
WHERE session_token_hash IS NOT NULL
|
|
14
|
+
AND session_token <> LOWER(SUBSTRING(HEX(session_token_hash), 1, 36));
|
|
15
|
+
|
|
16
|
+
ALTER TABLE web_google_session
|
|
17
|
+
MODIFY COLUMN session_token_hash BINARY(32) NOT NULL;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
DROP TABLE IF EXISTS ai_help_response_cache;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS ai_help_response_cache (
|
|
2
|
+
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
3
|
+
module_key VARCHAR(64) NOT NULL,
|
|
4
|
+
scope VARCHAR(32) NOT NULL DEFAULT 'question',
|
|
5
|
+
question_hash CHAR(64) NOT NULL,
|
|
6
|
+
normalized_question VARCHAR(512) NOT NULL,
|
|
7
|
+
original_question VARCHAR(512) DEFAULT NULL,
|
|
8
|
+
command_name VARCHAR(64) DEFAULT NULL,
|
|
9
|
+
answer_text MEDIUMTEXT NOT NULL,
|
|
10
|
+
source VARCHAR(32) NOT NULL DEFAULT 'deterministic',
|
|
11
|
+
model_name VARCHAR(80) DEFAULT NULL,
|
|
12
|
+
metadata JSON DEFAULT NULL,
|
|
13
|
+
hit_count INT UNSIGNED NOT NULL DEFAULT 1,
|
|
14
|
+
last_used_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
|
|
15
|
+
created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
|
|
16
|
+
updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
17
|
+
PRIMARY KEY (id),
|
|
18
|
+
UNIQUE KEY uq_ai_help_response_cache_lookup (module_key, scope, question_hash),
|
|
19
|
+
KEY idx_ai_help_response_cache_module_command_used (module_key, command_name, last_used_at),
|
|
20
|
+
KEY idx_ai_help_response_cache_used (last_used_at),
|
|
21
|
+
KEY idx_ai_help_response_cache_source_used (source, last_used_at)
|
|
22
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS ai_learning_events (
|
|
2
|
+
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
3
|
+
user_question VARCHAR(512) NOT NULL,
|
|
4
|
+
normalized_question VARCHAR(512) NOT NULL,
|
|
5
|
+
tool_suggested VARCHAR(64) NOT NULL,
|
|
6
|
+
tool_executed VARCHAR(64) NOT NULL,
|
|
7
|
+
success TINYINT(1) NOT NULL DEFAULT 1,
|
|
8
|
+
confidence DECIMAL(5,4) DEFAULT NULL,
|
|
9
|
+
processed TINYINT(1) NOT NULL DEFAULT 0,
|
|
10
|
+
processed_at TIMESTAMP NULL DEFAULT NULL,
|
|
11
|
+
created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
|
|
12
|
+
PRIMARY KEY (id),
|
|
13
|
+
KEY idx_ai_learning_events_processed_created (processed, created_at),
|
|
14
|
+
KEY idx_ai_learning_events_tool_created (tool_executed, created_at),
|
|
15
|
+
KEY idx_ai_learning_events_norm_question (normalized_question)
|
|
16
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
17
|
+
|
|
18
|
+
CREATE TABLE IF NOT EXISTS ai_learned_patterns (
|
|
19
|
+
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
20
|
+
pattern VARCHAR(512) NOT NULL,
|
|
21
|
+
tool VARCHAR(64) NOT NULL,
|
|
22
|
+
confidence DECIMAL(5,4) NOT NULL DEFAULT 0.5000,
|
|
23
|
+
source_event_id BIGINT UNSIGNED NOT NULL,
|
|
24
|
+
created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
|
|
25
|
+
PRIMARY KEY (id),
|
|
26
|
+
UNIQUE KEY uq_ai_learned_patterns_event_pattern (source_event_id, tool, pattern),
|
|
27
|
+
KEY idx_ai_learned_patterns_tool_created (tool, created_at),
|
|
28
|
+
KEY idx_ai_learned_patterns_tool_confidence (tool, confidence)
|
|
29
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
30
|
+
|
|
31
|
+
CREATE TABLE IF NOT EXISTS ai_learned_keywords (
|
|
32
|
+
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
33
|
+
keyword VARCHAR(128) NOT NULL,
|
|
34
|
+
tool VARCHAR(64) NOT NULL,
|
|
35
|
+
weight DECIMAL(6,4) NOT NULL DEFAULT 1.0000,
|
|
36
|
+
source_event_id BIGINT UNSIGNED NOT NULL,
|
|
37
|
+
created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
|
|
38
|
+
PRIMARY KEY (id),
|
|
39
|
+
UNIQUE KEY uq_ai_learned_keywords_event_keyword (source_event_id, tool, keyword),
|
|
40
|
+
KEY idx_ai_learned_keywords_tool_created (tool, created_at),
|
|
41
|
+
KEY idx_ai_learned_keywords_tool_weight (tool, weight)
|
|
42
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
43
|
+
|
|
44
|
+
CREATE TABLE IF NOT EXISTS ai_question_embeddings (
|
|
45
|
+
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
46
|
+
question VARCHAR(512) NOT NULL,
|
|
47
|
+
embedding LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(embedding)),
|
|
48
|
+
tool VARCHAR(64) NOT NULL,
|
|
49
|
+
created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
|
|
50
|
+
PRIMARY KEY (id),
|
|
51
|
+
KEY idx_ai_question_embeddings_tool_created (tool, created_at)
|
|
52
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS `ai_command_config_enrichment_cursor` (
|
|
2
|
+
`id` tinyint(3) unsigned NOT NULL DEFAULT 1,
|
|
3
|
+
`last_learning_event_id` bigint(20) unsigned NOT NULL DEFAULT 0,
|
|
4
|
+
`updated_at` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
|
5
|
+
`created_at` timestamp NULL DEFAULT current_timestamp(),
|
|
6
|
+
PRIMARY KEY (`id`)
|
|
7
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
8
|
+
|
|
9
|
+
CREATE TABLE IF NOT EXISTS `ai_command_config_enrichment_suggestion` (
|
|
10
|
+
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
|
11
|
+
`module_key` varchar(64) NOT NULL,
|
|
12
|
+
`command_name` varchar(64) NOT NULL,
|
|
13
|
+
`source_tool` varchar(64) DEFAULT NULL,
|
|
14
|
+
`source_event_id` bigint(20) unsigned DEFAULT NULL,
|
|
15
|
+
`user_question` varchar(512) DEFAULT NULL,
|
|
16
|
+
`normalized_question` varchar(512) DEFAULT NULL,
|
|
17
|
+
`suggestion_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`suggestion_json`)),
|
|
18
|
+
`confidence` decimal(5,4) NOT NULL DEFAULT 0.5000,
|
|
19
|
+
`model_name` varchar(80) DEFAULT NULL,
|
|
20
|
+
`source` varchar(32) NOT NULL DEFAULT 'llm',
|
|
21
|
+
`status` enum('pending','applied','rejected') NOT NULL DEFAULT 'pending',
|
|
22
|
+
`suggestion_hash` char(64) NOT NULL,
|
|
23
|
+
`review_notes` varchar(255) DEFAULT NULL,
|
|
24
|
+
`applied_at` timestamp NULL DEFAULT NULL,
|
|
25
|
+
`created_at` timestamp NULL DEFAULT current_timestamp(),
|
|
26
|
+
`updated_at` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
|
27
|
+
PRIMARY KEY (`id`),
|
|
28
|
+
UNIQUE KEY `uq_ai_command_cfg_enrichment_suggestion_hash` (`suggestion_hash`),
|
|
29
|
+
KEY `idx_ai_command_cfg_enrichment_module_command_status` (`module_key`,`command_name`,`status`,`updated_at`),
|
|
30
|
+
KEY `idx_ai_command_cfg_enrichment_source_event` (`source_event_id`,`updated_at`),
|
|
31
|
+
KEY `idx_ai_command_cfg_enrichment_status_updated` (`status`,`updated_at`)
|
|
32
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
33
|
+
|
|
34
|
+
CREATE TABLE IF NOT EXISTS `ai_command_config_enrichment_state` (
|
|
35
|
+
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
|
36
|
+
`module_key` varchar(64) NOT NULL,
|
|
37
|
+
`command_name` varchar(64) NOT NULL,
|
|
38
|
+
`overlay_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`overlay_json`)),
|
|
39
|
+
`version` int(10) unsigned NOT NULL DEFAULT 1,
|
|
40
|
+
`confidence` decimal(5,4) NOT NULL DEFAULT 0.5000,
|
|
41
|
+
`last_suggestion_id` bigint(20) unsigned DEFAULT NULL,
|
|
42
|
+
`created_at` timestamp NULL DEFAULT current_timestamp(),
|
|
43
|
+
`updated_at` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
|
44
|
+
PRIMARY KEY (`id`),
|
|
45
|
+
UNIQUE KEY `uq_ai_command_cfg_enrichment_state_module_command` (`module_key`,`command_name`),
|
|
46
|
+
KEY `idx_ai_command_cfg_enrichment_state_updated` (`updated_at`),
|
|
47
|
+
KEY `idx_ai_command_cfg_enrichment_state_last_suggestion` (`last_suggestion_id`)
|
|
48
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|