From eba336623003378a463835815f2ee558e3698a00 Mon Sep 17 00:00:00 2001 From: "gabriel.amancio" Date: Mon, 25 May 2026 15:58:59 -0300 Subject: [PATCH] =?UTF-8?q?FEAT:=20Cria=C3=A7=C3=A3o=20de=20fluxo=20para?= =?UTF-8?q?=20novos=20tipos=20de=20atendimento.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 767 +++++------------- package.json | 4 +- .../hubsoft/tickets.repository.js | 7 +- .../models/glpi/consultaBaseAtiva.model.js | 193 +++++ .../tickets/models/glpi/downgrade.model.js | 193 +++++ .../models/glpi/mudancaEndereco.model.js | 193 +++++ .../models/glpi/portabilidade.model.js | 193 +++++ .../tickets/models/glpi/upgrade.model.js | 193 +++++ .../tickets/repositories/ticket.repository.js | 82 +- .../services/consultaBaseAtiva.service.js | 43 + .../tickets/services/downgrade.service.js | 43 + .../services/mudancaEndereco.service.js | 43 + .../tickets/services/portabilidade.service.js | 43 + .../tickets/services/upgrade.service.js | 43 + .../tickets/useCases/syncTickets.usecase.js | 39 +- 15 files changed, 1503 insertions(+), 576 deletions(-) create mode 100644 src/modules/tickets/models/glpi/consultaBaseAtiva.model.js create mode 100644 src/modules/tickets/models/glpi/downgrade.model.js create mode 100644 src/modules/tickets/models/glpi/mudancaEndereco.model.js create mode 100644 src/modules/tickets/models/glpi/portabilidade.model.js create mode 100644 src/modules/tickets/models/glpi/upgrade.model.js create mode 100644 src/modules/tickets/services/consultaBaseAtiva.service.js create mode 100644 src/modules/tickets/services/downgrade.service.js create mode 100644 src/modules/tickets/services/mudancaEndereco.service.js create mode 100644 src/modules/tickets/services/portabilidade.service.js create mode 100644 src/modules/tickets/services/upgrade.service.js diff --git a/package-lock.json b/package-lock.json index 2cdad64..3180f1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,9 +15,9 @@ "express": "^5.1.0", "mysql2": "^3.15.2", "node-cron": "^4.2.1", - "nodemailer": "^7.0.12", + "nodemailer": "^8.0.7", "pg": "^8.16.3", - "pm2": "^6.0.13", + "pm2": "^7.0.1", "qs": "^6.14.0", "winston": "^3.18.3", "winston-daily-rotate-file": "^5.0.0" @@ -54,76 +54,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@pm2/agent": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@pm2/agent/-/agent-2.1.1.tgz", - "integrity": "sha512-0V9ckHWd/HSC8BgAbZSoq8KXUG81X97nSkAxmhKDhmF8vanyaoc1YXwc2KVkbWz82Rg4gjd2n9qiT3i7bdvGrQ==", - "license": "AGPL-3.0", - "dependencies": { - "async": "~3.2.0", - "chalk": "~3.0.0", - "dayjs": "~1.8.24", - "debug": "~4.3.1", - "eventemitter2": "~5.0.1", - "fast-json-patch": "^3.1.0", - "fclone": "~1.0.11", - "pm2-axon": "~4.0.1", - "pm2-axon-rpc": "~0.7.0", - "proxy-agent": "~6.4.0", - "semver": "~7.5.0", - "ws": "~7.5.10" - } - }, - "node_modules/@pm2/agent/node_modules/dayjs": { - "version": "1.8.36", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz", - "integrity": "sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==", - "license": "MIT" - }, - "node_modules/@pm2/agent/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@pm2/agent/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@pm2/agent/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@pm2/blessed": { "version": "0.1.81", "resolved": "https://registry.npmjs.org/@pm2/blessed/-/blessed-0.1.81.tgz", @@ -136,84 +66,6 @@ "node": ">= 0.8.0" } }, - "node_modules/@pm2/io": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@pm2/io/-/io-6.1.0.tgz", - "integrity": "sha512-IxHuYURa3+FQ6BKePlgChZkqABUKFYH6Bwbw7V/pWU1pP6iR1sCI26l7P9ThUEB385ruZn/tZS3CXDUF5IA1NQ==", - "license": "Apache-2", - "dependencies": { - "async": "~2.6.1", - "debug": "~4.3.1", - "eventemitter2": "^6.3.1", - "require-in-the-middle": "^5.0.0", - "semver": "~7.5.4", - "shimmer": "^1.2.0", - "signal-exit": "^3.0.3", - "tslib": "1.9.3" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/@pm2/io/node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "license": "MIT", - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/@pm2/io/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@pm2/io/node_modules/eventemitter2": { - "version": "6.4.9", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", - "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", - "license": "MIT" - }, - "node_modules/@pm2/io/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@pm2/io/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@pm2/js-api": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.8.0.tgz", @@ -256,12 +108,6 @@ } } }, - "node_modules/@pm2/js-api/node_modules/eventemitter2": { - "version": "6.4.9", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", - "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", - "license": "MIT" - }, "node_modules/@pm2/pm2-version-check": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@pm2/pm2-version-check/-/pm2-version-check-1.0.4.tgz", @@ -307,12 +153,15 @@ } }, "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "license": "MIT", + "dependencies": { + "debug": "4" + }, "engines": { - "node": ">= 14" + "node": ">= 6.0.0" } }, "node_modules/amp": { @@ -330,15 +179,6 @@ "amp": "0.3.1" } }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -412,12 +252,6 @@ "node": ">=4" } }, - "node_modules/ast-types/node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, "node_modules/async": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", @@ -440,14 +274,15 @@ } }, "node_modules/axios": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", - "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.1.tgz", + "integrity": "sha512-caYkukvroVPO8KrzuJEb50Hm07KwfBZPEC3VeFHTsqWHvKTsy54hjJz9BS/cdaypROE2rH6xvm9mHX4fgWkr3A==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", - "proxy-from-env": "^1.1.0" + "follow-redirects": "^1.16.0", + "form-data": "^4.0.5", + "https-proxy-agent": "^5.0.1", + "proxy-from-env": "^2.1.0" } }, "node_modules/balanced-match": { @@ -458,9 +293,9 @@ "license": "MIT" }, "node_modules/basic-ftp": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", - "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.1.tgz", + "integrity": "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -485,41 +320,33 @@ "license": "MIT" }, "node_modules/body-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", - "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", "license": "MIT", "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", - "debug": "^4.4.0", + "debug": "^4.4.3", "http-errors": "^2.0.0", - "iconv-lite": "^0.6.3", + "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.0", - "type-is": "^2.0.0" + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" }, "engines": { "node": ">=18" - } - }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", "dependencies": { @@ -539,12 +366,6 @@ "node": ">=8" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "license": "MIT" - }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -596,12 +417,6 @@ "node": ">=8" } }, - "node_modules/charm": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz", - "integrity": "sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ==", - "license": "MIT/X11" - }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -912,18 +727,6 @@ "node": ">= 0.8" } }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -975,18 +778,6 @@ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/escodegen": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", @@ -1049,9 +840,9 @@ } }, "node_modules/eventemitter2": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz", - "integrity": "sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg==", + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", "license": "MIT" }, "node_modules/express": { @@ -1111,12 +902,6 @@ "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==", "license": "MIT" }, - "node_modules/fclone": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", - "integrity": "sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==", - "license": "MIT" - }, "node_modules/fecha": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", @@ -1168,9 +953,9 @@ "license": "MIT" }, "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "funding": [ { "type": "individual", @@ -1188,9 +973,9 @@ } }, "node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -1447,17 +1232,26 @@ "node": ">= 14" } }, + "node_modules/http-proxy-agent/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "license": "MIT", "dependencies": { - "agent-base": "^7.1.2", + "agent-base": "6", "debug": "4" }, "engines": { - "node": ">= 14" + "node": ">= 6" } }, "node_modules/iconv-lite": { @@ -1496,9 +1290,9 @@ "license": "ISC" }, "node_modules/ip-address": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", + "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", "license": "MIT", "engines": { "node": ">= 12" @@ -1525,21 +1319,6 @@ "node": ">=8" } }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1614,9 +1393,9 @@ } }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -1639,9 +1418,9 @@ "license": "MIT" }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, "node_modules/logform": { @@ -1743,9 +1522,9 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -1755,24 +1534,6 @@ "node": "*" } }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/module-details-from-path": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", - "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", - "license": "MIT" - }, "node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", @@ -1788,12 +1549,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "license": "ISC" - }, "node_modules/mysql2": { "version": "3.15.2", "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.15.2.tgz", @@ -1826,44 +1581,6 @@ "node": ">=12.0.0" } }, - "node_modules/needle": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", - "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", - "license": "MIT", - "dependencies": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - }, - "bin": { - "needle": "bin/needle" - }, - "engines": { - "node": ">= 4.4.x" - } - }, - "node_modules/needle/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/needle/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/negotiator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", @@ -1874,9 +1591,9 @@ } }, "node_modules/netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.1.1.tgz", + "integrity": "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==", "license": "MIT", "engines": { "node": ">= 0.4.0" @@ -1892,9 +1609,9 @@ } }, "node_modules/nodemailer": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.12.tgz", - "integrity": "sha512-H+rnK5bX2Pi/6ms3sN4/jRQvYSMltV6vqup/0SFOrxYYY/qoNvhXPlYq3e+Pm9RFJRwrMGbMIwi81M4dxpomhA==", + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.7.tgz", + "integrity": "sha512-pkjE4mkBzQjdJT4/UmlKl3pX0rC9fZmjh7c6C9o7lv66Ac6w9WCnzPzhbPNxwZAzlF4mdq4CSWB5+FbK6FWCow==", "license": "MIT-0", "engines": { "node": ">=6.0.0" @@ -2031,6 +1748,28 @@ "node": ">= 14" } }, + "node_modules/pac-proxy-agent/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/pac-resolver": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", @@ -2069,16 +1808,10 @@ "node": ">=8" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "license": "MIT" - }, "node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", "license": "MIT", "funding": { "type": "opencollective", @@ -2175,9 +1908,9 @@ } }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "license": "MIT", "engines": { "node": ">=8.6" @@ -2187,28 +1920,28 @@ } }, "node_modules/pidusage": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-3.0.2.tgz", - "integrity": "sha512-g0VU+y08pKw5M8EZ2rIGiEBaB8wrQMjYGFfW2QVIfyT8V+fq8YFLkvlz4bz5ljvFDJYNFCWT3PWqcRr2FKO81w==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-4.0.1.tgz", + "integrity": "sha512-yCH2dtLHfEBnzlHUJymR/Z1nN2ePG3m392Mv8TFlTP1B0xkpMQNHAnfkY0n2tAi6ceKO6YWhxYfZ96V4vVkh/g==", "license": "MIT", "dependencies": { "safe-buffer": "^5.2.1" }, "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/pm2": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/pm2/-/pm2-6.0.13.tgz", - "integrity": "sha512-1hS/adMgKoDpX4S1ichJW8SiGpex+oBSZK31dP1FSYOOGtaeuemXzhXPOCefmddgIY4K6v7uu+7xNPnmEnK3ag==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pm2/-/pm2-7.0.1.tgz", + "integrity": "sha512-h/DI7WomfdAWDzDRtjhnNfsG4Do6kuOY+VGKbqffHW3yRZMUoWzwyBDkXjrOWvnBlwuY3lYBKkozDdCagfRI4Q==", "license": "AGPL-3.0", "dependencies": { - "@pm2/agent": "~2.1.1", "@pm2/blessed": "0.1.81", - "@pm2/io": "~6.1.0", - "@pm2/js-api": "~0.8.0", - "@pm2/pm2-version-check": "latest", + "@pm2/js-api": "0.8.0", + "@pm2/pm2-version-check": "1.0.4", + "amp": "0.3.1", + "amp-message": "0.1.2", "ansis": "4.0.0-node10", "async": "3.2.6", "chokidar": "3.6.0", @@ -2217,22 +1950,15 @@ "croner": "4.1.97", "dayjs": "1.11.15", "debug": "4.4.3", - "enquirer": "2.3.6", - "eventemitter2": "5.0.1", - "fclone": "1.0.11", - "js-yaml": "4.1.0", - "mkdirp": "1.0.4", - "needle": "2.4.0", - "pidusage": "3.0.2", - "pm2-axon": "~4.0.1", - "pm2-axon-rpc": "~0.7.1", - "pm2-deploy": "~1.0.2", - "pm2-multimeter": "^0.1.2", - "promptly": "2.2.0", + "eventemitter2": "6.4.9", + "fast-json-patch": "3.1.1", + "js-yaml": "4.1.1", + "pidusage": "4.0.1", + "pm2-deploy": "1.0.2", + "proxy-agent": "6.5.0", "semver": "7.7.2", - "source-map-support": "0.5.21", - "sprintf-js": "1.1.2", - "vizion": "~2.2.1" + "vizion": "2.2.1", + "ws": "8.20.0" }, "bin": { "pm2": "bin/pm2", @@ -2241,39 +1967,12 @@ "pm2-runtime": "bin/pm2-runtime" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "optionalDependencies": { "pm2-sysmonit": "^1.2.8" } }, - "node_modules/pm2-axon": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pm2-axon/-/pm2-axon-4.0.1.tgz", - "integrity": "sha512-kES/PeSLS8orT8dR5jMlNl+Yu4Ty3nbvZRmaAtROuVm9nYYGiaoXqqKQqQYzWQzMYWUKHMQTvBlirjE5GIIxqg==", - "license": "MIT", - "dependencies": { - "amp": "~0.3.1", - "amp-message": "~0.1.1", - "debug": "^4.3.1", - "escape-string-regexp": "^4.0.0" - }, - "engines": { - "node": ">=5" - } - }, - "node_modules/pm2-axon-rpc": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/pm2-axon-rpc/-/pm2-axon-rpc-0.7.1.tgz", - "integrity": "sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.1" - }, - "engines": { - "node": ">=5" - } - }, "node_modules/pm2-deploy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pm2-deploy/-/pm2-deploy-1.0.2.tgz", @@ -2287,15 +1986,6 @@ "node": ">=4.0.0" } }, - "node_modules/pm2-multimeter": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/pm2-multimeter/-/pm2-multimeter-0.1.2.tgz", - "integrity": "sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA==", - "license": "MIT/X11", - "dependencies": { - "charm": "~0.1.1" - } - }, "node_modules/pm2-sysmonit": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/pm2-sysmonit/-/pm2-sysmonit-1.2.8.tgz", @@ -2323,6 +2013,27 @@ "node": ">=8" } }, + "node_modules/pm2/node_modules/ws": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/postgres-array": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", @@ -2362,15 +2073,6 @@ "node": ">=0.10.0" } }, - "node_modules/promptly": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/promptly/-/promptly-2.2.0.tgz", - "integrity": "sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA==", - "license": "MIT", - "dependencies": { - "read": "^1.0.4" - } - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -2385,30 +2087,61 @@ } }, "node_modules/proxy-agent": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", - "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.3", + "https-proxy-agent": "^7.0.6", "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.1", + "pac-proxy-agent": "^7.1.0", "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.2" + "socks-proxy-agent": "^8.0.5" }, "engines": { "node": ">= 14" } }, - "node_modules/proxy-from-env": { + "node_modules/proxy-agent/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "license": "MIT" }, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", @@ -2417,9 +2150,9 @@ "license": "MIT" }, "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "version": "6.15.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz", + "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -2455,18 +2188,6 @@ "node": ">= 0.10" } }, - "node_modules/read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", - "license": "ISC", - "dependencies": { - "mute-stream": "~0.0.4" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -2493,40 +2214,6 @@ "node": ">=8.10.0" } }, - "node_modules/require-in-the-middle": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.2.0.tgz", - "integrity": "sha512-efCx3b+0Z69/LGJmm9Yvi4cqEdxnoGnxYxGxBghkkTTFeXRtTCmmhO0AnAfHz59k957uTSuy8WaHqOs8wbYUWg==", - "license": "MIT", - "dependencies": { - "debug": "^4.1.1", - "module-details-from-path": "^1.0.3", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/resolve": { - "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/router": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", @@ -2598,12 +2285,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, - "node_modules/sax": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.3.tgz", - "integrity": "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==", - "license": "BlueOak-1.0.0" - }, "node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", @@ -2687,12 +2368,6 @@ "node": ">=8" } }, - "node_modules/shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", - "license": "BSD-2-Clause" - }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", @@ -2765,12 +2440,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" - }, "node_modules/simple-update-notifier": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", @@ -2795,12 +2464,12 @@ } }, "node_modules/socks": { - "version": "2.8.7", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", - "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.9.tgz", + "integrity": "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==", "license": "MIT", "dependencies": { - "ip-address": "^10.0.1", + "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" }, "engines": { @@ -2822,25 +2491,25 @@ "node": ">= 14" } }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "license": "BSD-3-Clause", + "optional": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "node_modules/split2": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", @@ -2850,12 +2519,6 @@ "node": ">= 10.x" } }, - "node_modules/sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "license": "BSD-3-Clause" - }, "node_modules/sqlstring": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", @@ -2904,22 +2567,10 @@ "node": ">=8" } }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/systeminformation": { - "version": "5.27.11", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.27.11.tgz", - "integrity": "sha512-K3Lto/2m3K2twmKHdgx5B+0in9qhXK4YnoT9rIlgwN/4v7OV5c8IjbeAUkuky/6VzCQC7iKCAqi8rZathCdjHg==", + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.31.6.tgz", + "integrity": "sha512-Uv2b2uGGM6ns+26czgW2cYRabYdnswM0ddSOOlryHOaelzsmDSet1iM/NT7VOYxW8x/BW+HkY+b1Ve2pLTSGSA==", "license": "MIT", "optional": true, "os": [ @@ -2990,10 +2641,10 @@ } }, "node_modules/tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "license": "Apache-2.0" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/tv4": { "version": "1.3.0", @@ -3197,12 +2848,6 @@ "engines": { "node": ">=0.4" } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" } } } diff --git a/package.json b/package.json index 8f2864a..24844a8 100644 --- a/package.json +++ b/package.json @@ -21,9 +21,9 @@ "express": "^5.1.0", "mysql2": "^3.15.2", "node-cron": "^4.2.1", - "nodemailer": "^7.0.12", + "nodemailer": "^8.0.7", "pg": "^8.16.3", - "pm2": "^6.0.13", + "pm2": "^7.0.1", "qs": "^6.14.0", "winston": "^3.18.3", "winston-daily-rotate-file": "^5.0.0" diff --git a/src/infra/db/repositories/hubsoft/tickets.repository.js b/src/infra/db/repositories/hubsoft/tickets.repository.js index 7bbef13..614f523 100644 --- a/src/infra/db/repositories/hubsoft/tickets.repository.js +++ b/src/infra/db/repositories/hubsoft/tickets.repository.js @@ -11,9 +11,8 @@ async function getTicketsByTipo({ watermark = null }) { try { - const isImplantacao = Number(tipoAtendimento) === 21; - const isCancelamento = Number(tipoAtendimento) === 27; - const istrocaTitularidade = Number(tipoAtendimento) === 60; + const TIPOS_COM_DADOS_COMPLETOS = [4, 21, 27, 41, 60, 22, 25, 7, 61, 63]; + const temDadosCompletos = TIPOS_COM_DADOS_COMPLETOS.includes(Number(tipoAtendimento)); let select = ` a.id_atendimento, @@ -35,7 +34,7 @@ async function getTicketsByTipo({ INNER JOIN servico AS s ON cs.id_servico = s.id_servico `; - if (isImplantacao || isCancelamento || istrocaTitularidade) { + if (temDadosCompletos) { select += `, u.name AS vendedor, c.nome_razaosocial, diff --git a/src/modules/tickets/models/glpi/consultaBaseAtiva.model.js b/src/modules/tickets/models/glpi/consultaBaseAtiva.model.js new file mode 100644 index 0000000..11ffbf2 --- /dev/null +++ b/src/modules/tickets/models/glpi/consultaBaseAtiva.model.js @@ -0,0 +1,193 @@ +// src/modules/tickets/models/glpi/consultaBaseAtiva.model.js + +function toGlpiPayload(ticket) { + return { + entities_id: ticket.entities_id || 0, + name: buildTitle(ticket), + content: buildHtml(ticket), + status: resolveGlpiStatus(ticket.status_atendimento), + date: ticket.created_at, + date_mod: new Date(), + users_id_recipient: process.env.GLPI_USER_ID || 0, + urgency: 3, + impact: 3, + priority: 3, + type: 2, + date_creation: ticket.created_at || new Date(), + itilcategories_id: 0, + slas_id_ttr: 37, + } +} + +function resolveGlpiStatus(status) { + const map = { + 'Novo': 1, + 'Pendente': 4, + 'Em atendimento': 2, + 'Resolvido': 5 + } + return map[status] || 1 +} + +function buildTitle(ticket) { + return `CONSULTA BASE ATIVA - ${ticket.codigo_cliente}-${ticket.codigo_servico} - ${ticket.nome_razaosocial} - ${ticket.servico_nome}` +} + +function buildHtml(ticket) { + const docLabel = ticket.tipo_pessoa === 'pf' ? 'CPF' : 'CNPJ' + const documento = formatDocument(ticket.cpf_cnpj, ticket.tipo_pessoa) + const servico = resolveService(ticket.servico_nome) + + return ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Dados Comercial +
Nº de Operação${ticket.protocolo_hub || "N/A"}
Gerente Responsável${ticket.vendedor || "N/A"}
Código do Cliente${ticket.codigo_cliente}
+ Dados Cliente +
Cliente${ticket.nome_razaosocial}
${docLabel}${documento}
Nome Contato${ticket.cliente_nome || "N/A"}
Email Contato${ticket.email || "N/A"}
Telefone Contato${ticket.telefone || "N/A"}
Endereço Instalação${ticket.endereco || "N/A"}
+ Dados do Serviço Contratado +
+ + + + + + + + + + + +
ProdutoQuantidadeDescrição
${servico.produto}${servico.qtd}${servico.descricao || ""}
+
+ Observações +
+ ${nl2br(ticket.descricao_abertura) || "N/A"} +
+` +} + + +function formatCPF(cpf) { + return cpf?.replace(/\D/g, '') + .replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4') +} + +function formatCNPJ(cnpj) { + return cnpj?.replace(/\D/g, '') + .replace(/(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})/, '$1.$2.$3/$4-$5') +} + +function formatDocument(doc, tipo) { + if (!doc) return 'N/A' + return tipo === 'pf' ? formatCPF(doc) : formatCNPJ(doc) +} + +const serviceDictionary = { + // ---------- LAN-TO-LAN ---------- + "Lan-to-Lan 50 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "50 Mbps" }, + "Lan-to-Lan 100 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "100 Mbps" }, + "Lan-to-Lan 200 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "200 Mbps" }, + "Lan-to-Lan 300 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "300 Mbps" }, + "Lan-to-Lan 500 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "500 Mbps" }, + "Lan-to-Lan 700 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "700 Mbps" }, + "Lan-to-Lan": { produto: "Lan-to-Lan", qtd: 1, descricao: null }, + + "Link de Internet Dedicado 20 Mbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "20 Mbps Full Duplex" }, + + "Link de Internet Dedicado 100 Mbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "100 Mbps Full Duplex" }, + + "Link de Internet Dedicado 1Gbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "1 Gbps Full Duplex" }, + + "Link de Internet Dedicado 2 Gbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "2 Gbps Full Duplex" }, + +}; + +function resolveService(name) { + return serviceDictionary[name] || { produto: name, qtd: 1, descricao: null } +} + +function nl2br(text) { + if (!text) return '' + return text.replace(/\r\n|\n|\r/g, '
') +} + +module.exports = { toGlpiPayload } \ No newline at end of file diff --git a/src/modules/tickets/models/glpi/downgrade.model.js b/src/modules/tickets/models/glpi/downgrade.model.js new file mode 100644 index 0000000..6cf5215 --- /dev/null +++ b/src/modules/tickets/models/glpi/downgrade.model.js @@ -0,0 +1,193 @@ +// src/modules/tickets/models/glpi/downgrade.model.js + +function toGlpiPayload(ticket) { + return { + entities_id: ticket.entities_id || 0, + name: buildTitle(ticket), + content: buildHtml(ticket), + status: resolveGlpiStatus(ticket.status_atendimento), + date: ticket.created_at, + date_mod: new Date(), + users_id_recipient: process.env.GLPI_USER_ID || 0, + urgency: 3, + impact: 3, + priority: 3, + type: 2, + date_creation: ticket.created_at || new Date(), + itilcategories_id: 0, + slas_id_ttr: 37, + } +} + +function resolveGlpiStatus(status) { + const map = { + 'Novo': 1, + 'Pendente': 4, + 'Em atendimento': 2, + 'Resolvido': 5 + } + return map[status] || 1 +} + +function buildTitle(ticket) { + return `DOWNGRADE - ${ticket.codigo_cliente}-${ticket.codigo_servico} - ${ticket.nome_razaosocial} - ${ticket.servico_nome}` +} + +function buildHtml(ticket) { + const docLabel = ticket.tipo_pessoa === 'pf' ? 'CPF' : 'CNPJ' + const documento = formatDocument(ticket.cpf_cnpj, ticket.tipo_pessoa) + const servico = resolveService(ticket.servico_nome) + + return ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Dados Comercial +
Nº de Operação${ticket.protocolo_hub || "N/A"}
Gerente Responsável${ticket.vendedor || "N/A"}
Código do Cliente${ticket.codigo_cliente}
+ Dados Cliente +
Cliente${ticket.nome_razaosocial}
${docLabel}${documento}
Nome Contato${ticket.cliente_nome || "N/A"}
Email Contato${ticket.email || "N/A"}
Telefone Contato${ticket.telefone || "N/A"}
Endereço Instalação${ticket.endereco || "N/A"}
+ Dados do Serviço Contratado +
+ + + + + + + + + + + +
ProdutoQuantidadeDescrição
${servico.produto}${servico.qtd}${servico.descricao || ""}
+
+ Observações +
+ ${nl2br(ticket.descricao_abertura) || "N/A"} +
+` +} + + +function formatCPF(cpf) { + return cpf?.replace(/\D/g, '') + .replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4') +} + +function formatCNPJ(cnpj) { + return cnpj?.replace(/\D/g, '') + .replace(/(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})/, '$1.$2.$3/$4-$5') +} + +function formatDocument(doc, tipo) { + if (!doc) return 'N/A' + return tipo === 'pf' ? formatCPF(doc) : formatCNPJ(doc) +} + +const serviceDictionary = { + // ---------- LAN-TO-LAN ---------- + "Lan-to-Lan 50 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "50 Mbps" }, + "Lan-to-Lan 100 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "100 Mbps" }, + "Lan-to-Lan 200 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "200 Mbps" }, + "Lan-to-Lan 300 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "300 Mbps" }, + "Lan-to-Lan 500 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "500 Mbps" }, + "Lan-to-Lan 700 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "700 Mbps" }, + "Lan-to-Lan": { produto: "Lan-to-Lan", qtd: 1, descricao: null }, + + "Link de Internet Dedicado 20 Mbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "20 Mbps Full Duplex" }, + + "Link de Internet Dedicado 100 Mbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "100 Mbps Full Duplex" }, + + "Link de Internet Dedicado 1Gbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "1 Gbps Full Duplex" }, + + "Link de Internet Dedicado 2 Gbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "2 Gbps Full Duplex" }, + +}; + +function resolveService(name) { + return serviceDictionary[name] || { produto: name, qtd: 1, descricao: null } +} + +function nl2br(text) { + if (!text) return '' + return text.replace(/\r\n|\n|\r/g, '
') +} + +module.exports = { toGlpiPayload } \ No newline at end of file diff --git a/src/modules/tickets/models/glpi/mudancaEndereco.model.js b/src/modules/tickets/models/glpi/mudancaEndereco.model.js new file mode 100644 index 0000000..bf53181 --- /dev/null +++ b/src/modules/tickets/models/glpi/mudancaEndereco.model.js @@ -0,0 +1,193 @@ +// src/modules/tickets/models/glpi/mudancaEndereco.model.js + +function toGlpiPayload(ticket) { + return { + entities_id: ticket.entities_id || 0, + name: buildTitle(ticket), + content: buildHtml(ticket), + status: resolveGlpiStatus(ticket.status_atendimento), + date: ticket.created_at, + date_mod: new Date(), + users_id_recipient: process.env.GLPI_USER_ID || 0, + urgency: 3, + impact: 3, + priority: 3, + type: 2, + date_creation: ticket.created_at || new Date(), + itilcategories_id: 0, + slas_id_ttr: 37, + } +} + +function resolveGlpiStatus(status) { + const map = { + 'Novo': 1, + 'Pendente': 4, + 'Em atendimento': 2, + 'Resolvido': 5 + } + return map[status] || 1 +} + +function buildTitle(ticket) { + return `MUDANCA DE ENDERECO - ${ticket.codigo_cliente}-${ticket.codigo_servico} - ${ticket.nome_razaosocial} - ${ticket.servico_nome}` +} + +function buildHtml(ticket) { + const docLabel = ticket.tipo_pessoa === 'pf' ? 'CPF' : 'CNPJ' + const documento = formatDocument(ticket.cpf_cnpj, ticket.tipo_pessoa) + const servico = resolveService(ticket.servico_nome) + + return ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Dados Comercial +
Nº de Operação${ticket.protocolo_hub || "N/A"}
Gerente Responsável${ticket.vendedor || "N/A"}
Código do Cliente${ticket.codigo_cliente}
+ Dados Cliente +
Cliente${ticket.nome_razaosocial}
${docLabel}${documento}
Nome Contato${ticket.cliente_nome || "N/A"}
Email Contato${ticket.email || "N/A"}
Telefone Contato${ticket.telefone || "N/A"}
Endereço Instalação${ticket.endereco || "N/A"}
+ Dados do Serviço Contratado +
+ + + + + + + + + + + +
ProdutoQuantidadeDescrição
${servico.produto}${servico.qtd}${servico.descricao || ""}
+
+ Observações +
+ ${nl2br(ticket.descricao_abertura) || "N/A"} +
+` +} + + +function formatCPF(cpf) { + return cpf?.replace(/\D/g, '') + .replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4') +} + +function formatCNPJ(cnpj) { + return cnpj?.replace(/\D/g, '') + .replace(/(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})/, '$1.$2.$3/$4-$5') +} + +function formatDocument(doc, tipo) { + if (!doc) return 'N/A' + return tipo === 'pf' ? formatCPF(doc) : formatCNPJ(doc) +} + +const serviceDictionary = { + // ---------- LAN-TO-LAN ---------- + "Lan-to-Lan 50 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "50 Mbps" }, + "Lan-to-Lan 100 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "100 Mbps" }, + "Lan-to-Lan 200 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "200 Mbps" }, + "Lan-to-Lan 300 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "300 Mbps" }, + "Lan-to-Lan 500 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "500 Mbps" }, + "Lan-to-Lan 700 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "700 Mbps" }, + "Lan-to-Lan": { produto: "Lan-to-Lan", qtd: 1, descricao: null }, + + "Link de Internet Dedicado 20 Mbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "20 Mbps Full Duplex" }, + + "Link de Internet Dedicado 100 Mbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "100 Mbps Full Duplex" }, + + "Link de Internet Dedicado 1Gbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "1 Gbps Full Duplex" }, + + "Link de Internet Dedicado 2 Gbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "2 Gbps Full Duplex" }, + +}; + +function resolveService(name) { + return serviceDictionary[name] || { produto: name, qtd: 1, descricao: null } +} + +function nl2br(text) { + if (!text) return '' + return text.replace(/\r\n|\n|\r/g, '
') +} + +module.exports = { toGlpiPayload } \ No newline at end of file diff --git a/src/modules/tickets/models/glpi/portabilidade.model.js b/src/modules/tickets/models/glpi/portabilidade.model.js new file mode 100644 index 0000000..e23ca45 --- /dev/null +++ b/src/modules/tickets/models/glpi/portabilidade.model.js @@ -0,0 +1,193 @@ +// src/modules/tickets/models/glpi/portabilidade.model.js + +function toGlpiPayload(ticket) { + return { + entities_id: ticket.entities_id || 0, + name: buildTitle(ticket), + content: buildHtml(ticket), + status: resolveGlpiStatus(ticket.status_atendimento), + date: ticket.created_at, + date_mod: new Date(), + users_id_recipient: process.env.GLPI_USER_ID || 0, + urgency: 3, + impact: 3, + priority: 3, + type: 2, + date_creation: ticket.created_at || new Date(), + itilcategories_id: 0, + slas_id_ttr: 37, + } +} + +function resolveGlpiStatus(status) { + const map = { + 'Novo': 1, + 'Pendente': 4, + 'Em atendimento': 2, + 'Resolvido': 5 + } + return map[status] || 1 +} + +function buildTitle(ticket) { + return `PORTABILIDADE - ${ticket.codigo_cliente}-${ticket.codigo_servico} - ${ticket.nome_razaosocial} - ${ticket.servico_nome}` +} + +function buildHtml(ticket) { + const docLabel = ticket.tipo_pessoa === 'pf' ? 'CPF' : 'CNPJ' + const documento = formatDocument(ticket.cpf_cnpj, ticket.tipo_pessoa) + const servico = resolveService(ticket.servico_nome) + + return ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Dados Comercial +
Nº de Operação${ticket.protocolo_hub || "N/A"}
Gerente Responsável${ticket.vendedor || "N/A"}
Código do Cliente${ticket.codigo_cliente}
+ Dados Cliente +
Cliente${ticket.nome_razaosocial}
${docLabel}${documento}
Nome Contato${ticket.cliente_nome || "N/A"}
Email Contato${ticket.email || "N/A"}
Telefone Contato${ticket.telefone || "N/A"}
Endereço Instalação${ticket.endereco || "N/A"}
+ Dados do Serviço Contratado +
+ + + + + + + + + + + +
ProdutoQuantidadeDescrição
${servico.produto}${servico.qtd}${servico.descricao || ""}
+
+ Observações +
+ ${nl2br(ticket.descricao_abertura) || "N/A"} +
+` +} + + +function formatCPF(cpf) { + return cpf?.replace(/\D/g, '') + .replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4') +} + +function formatCNPJ(cnpj) { + return cnpj?.replace(/\D/g, '') + .replace(/(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})/, '$1.$2.$3/$4-$5') +} + +function formatDocument(doc, tipo) { + if (!doc) return 'N/A' + return tipo === 'pf' ? formatCPF(doc) : formatCNPJ(doc) +} + +const serviceDictionary = { + // ---------- LAN-TO-LAN ---------- + "Lan-to-Lan 50 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "50 Mbps" }, + "Lan-to-Lan 100 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "100 Mbps" }, + "Lan-to-Lan 200 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "200 Mbps" }, + "Lan-to-Lan 300 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "300 Mbps" }, + "Lan-to-Lan 500 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "500 Mbps" }, + "Lan-to-Lan 700 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "700 Mbps" }, + "Lan-to-Lan": { produto: "Lan-to-Lan", qtd: 1, descricao: null }, + + "Link de Internet Dedicado 20 Mbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "20 Mbps Full Duplex" }, + + "Link de Internet Dedicado 100 Mbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "100 Mbps Full Duplex" }, + + "Link de Internet Dedicado 1Gbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "1 Gbps Full Duplex" }, + + "Link de Internet Dedicado 2 Gbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "2 Gbps Full Duplex" }, + +}; + +function resolveService(name) { + return serviceDictionary[name] || { produto: name, qtd: 1, descricao: null } +} + +function nl2br(text) { + if (!text) return '' + return text.replace(/\r\n|\n|\r/g, '
') +} + +module.exports = { toGlpiPayload } \ No newline at end of file diff --git a/src/modules/tickets/models/glpi/upgrade.model.js b/src/modules/tickets/models/glpi/upgrade.model.js new file mode 100644 index 0000000..dd91192 --- /dev/null +++ b/src/modules/tickets/models/glpi/upgrade.model.js @@ -0,0 +1,193 @@ +// src/modules/tickets/models/glpi/upgrade.model.js + +function toGlpiPayload(ticket) { + return { + entities_id: ticket.entities_id || 0, + name: buildTitle(ticket), + content: buildHtml(ticket), + status: resolveGlpiStatus(ticket.status_atendimento), + date: ticket.created_at, + date_mod: new Date(), + users_id_recipient: process.env.GLPI_USER_ID || 0, + urgency: 3, + impact: 3, + priority: 3, + type: 2, + date_creation: ticket.created_at || new Date(), + itilcategories_id: 0, + slas_id_ttr: 37, + } +} + +function resolveGlpiStatus(status) { + const map = { + 'Novo': 1, + 'Pendente': 4, + 'Em atendimento': 2, + 'Resolvido': 5 + } + return map[status] || 1 +} + +function buildTitle(ticket) { + return `UPGRADE - ${ticket.codigo_cliente}-${ticket.codigo_servico} - ${ticket.nome_razaosocial} - ${ticket.servico_nome}` +} + +function buildHtml(ticket) { + const docLabel = ticket.tipo_pessoa === 'pf' ? 'CPF' : 'CNPJ' + const documento = formatDocument(ticket.cpf_cnpj, ticket.tipo_pessoa) + const servico = resolveService(ticket.servico_nome) + + return ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Dados Comercial +
Nº de Operação${ticket.protocolo_hub || "N/A"}
Gerente Responsável${ticket.vendedor || "N/A"}
Código do Cliente${ticket.codigo_cliente}
+ Dados Cliente +
Cliente${ticket.nome_razaosocial}
${docLabel}${documento}
Nome Contato${ticket.cliente_nome || "N/A"}
Email Contato${ticket.email || "N/A"}
Telefone Contato${ticket.telefone || "N/A"}
Endereço Instalação${ticket.endereco || "N/A"}
+ Dados do Serviço Contratado +
+ + + + + + + + + + + +
ProdutoQuantidadeDescrição
${servico.produto}${servico.qtd}${servico.descricao || ""}
+
+ Observações +
+ ${nl2br(ticket.descricao_abertura) || "N/A"} +
+` +} + + +function formatCPF(cpf) { + return cpf?.replace(/\D/g, '') + .replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4') +} + +function formatCNPJ(cnpj) { + return cnpj?.replace(/\D/g, '') + .replace(/(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})/, '$1.$2.$3/$4-$5') +} + +function formatDocument(doc, tipo) { + if (!doc) return 'N/A' + return tipo === 'pf' ? formatCPF(doc) : formatCNPJ(doc) +} + +const serviceDictionary = { + // ---------- LAN-TO-LAN ---------- + "Lan-to-Lan 50 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "50 Mbps" }, + "Lan-to-Lan 100 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "100 Mbps" }, + "Lan-to-Lan 200 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "200 Mbps" }, + "Lan-to-Lan 300 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "300 Mbps" }, + "Lan-to-Lan 500 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "500 Mbps" }, + "Lan-to-Lan 700 Mbps": { produto: "Lan-to-Lan", qtd: 1, descricao: "700 Mbps" }, + "Lan-to-Lan": { produto: "Lan-to-Lan", qtd: 1, descricao: null }, + + "Link de Internet Dedicado 20 Mbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "20 Mbps Full Duplex" }, + + "Link de Internet Dedicado 100 Mbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "100 Mbps Full Duplex" }, + + "Link de Internet Dedicado 1Gbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "1 Gbps Full Duplex" }, + + "Link de Internet Dedicado 2 Gbps Full Duplex": + { produto: "Link de Internet Dedicado", qtd: 1, descricao: "2 Gbps Full Duplex" }, + +}; + +function resolveService(name) { + return serviceDictionary[name] || { produto: name, qtd: 1, descricao: null } +} + +function nl2br(text) { + if (!text) return '' + return text.replace(/\r\n|\n|\r/g, '
') +} + +module.exports = { toGlpiPayload } \ No newline at end of file diff --git a/src/modules/tickets/repositories/ticket.repository.js b/src/modules/tickets/repositories/ticket.repository.js index 09c86b7..9178632 100644 --- a/src/modules/tickets/repositories/ticket.repository.js +++ b/src/modules/tickets/repositories/ticket.repository.js @@ -26,18 +26,23 @@ const TYPES = Object.freeze({ IMPLANTACAO: 21, CANCELAMENTO: 27, SAC: 41, - TITULARIDADE: 60 + TITULARIDADE: 60, + UPGRADE: 22, + DOWNGRADE: 25, + MUDANCA_ENDERECO: 7, + PORTABILIDADE: 61, + CONSULTA_BASE_ATIVA: 63 }); const RESPONSAVEL_LOOKBACK_DAYS = parsePositiveIntegerEnv( - process.env.HUBSOFT_RESPONSAVEL_LOOKBACK_DAYS, + process.env.HUBSOFT_SUPORTE_USER_ID, 365 ); async function getMundialeTickets(watermark) { return hubsoftTicketsRepo.getTicketsByTipo({ tipoAtendimento: TYPES.MUNDIALE, - usuarioAbertura: process.env.HUBSOFT_MUNDIALE_USER_ID, + usuarioAbertura: process.env.HUBSOFT_SUPORTE_USER_ID, watermark }); } @@ -46,7 +51,7 @@ async function getImplantacaoTickets(watermark) { return hubsoftTicketsRepo.getTicketsByTipo({ tipoAtendimento: TYPES.IMPLANTACAO, usuariosResponsaveisIds: parseCsvNumberEnv( - process.env.HUBSOFT_IMPLANTACAO_RESPONSAVEL_USER_IDS, + process.env.HUBSOFT_SUPORTE_USER_ID, [142] ), lookbackDays: RESPONSAVEL_LOOKBACK_DAYS, @@ -58,7 +63,7 @@ async function getCancelamentoTickets(watermark) { return hubsoftTicketsRepo.getTicketsByTipo({ tipoAtendimento: TYPES.CANCELAMENTO, usuariosResponsaveisIds: parseCsvNumberEnv( - process.env.HUBSOFT_CANCELAMENTO_RESPONSAVEL_USER_IDS, + process.env.HUBSOFT_SUPORTE_USER_ID, [142] ), lookbackDays: RESPONSAVEL_LOOKBACK_DAYS, @@ -77,7 +82,66 @@ async function getTrocaTTickets(watermark) { return hubsoftTicketsRepo.getTicketsByTipo({ tipoAtendimento: TYPES.TITULARIDADE, usuariosResponsaveisIds: parseCsvNumberEnv( - process.env.HUBSOFT_TITULARIDADE_RESPONSAVEL_USER_IDS, + process.env.HUBSOFT_SUPORTE_USER_ID, + [142] + ), + lookbackDays: RESPONSAVEL_LOOKBACK_DAYS, + watermark + }); +} + +async function getUpgradeTickets(watermark) { + return hubsoftTicketsRepo.getTicketsByTipo({ + tipoAtendimento: TYPES.UPGRADE, + usuariosResponsaveisIds: parseCsvNumberEnv( + process.env.HUBSOFT_SUPORTE_USER_ID, + [142] ), + lookbackDays: RESPONSAVEL_LOOKBACK_DAYS, + watermark + }); +} + +async function getDowngradeTickets(watermark) { + return hubsoftTicketsRepo.getTicketsByTipo({ + tipoAtendimento: TYPES.DOWNGRADE, + usuariosResponsaveisIds: parseCsvNumberEnv( + process.env.HUBSOFT_SUPORTE_USER_ID, + [142] + ), + lookbackDays: RESPONSAVEL_LOOKBACK_DAYS, + watermark + }); +} + +async function getMudancaEnderecoTickets(watermark) { + return hubsoftTicketsRepo.getTicketsByTipo({ + tipoAtendimento: TYPES.MUDANCA_ENDERECO, + usuariosResponsaveisIds: parseCsvNumberEnv( + process.env.HUBSOFT_SUPORTE_USER_ID, + [142] + ), + lookbackDays: RESPONSAVEL_LOOKBACK_DAYS, + watermark + }); +} + +async function getPortabilidadeTickets(watermark) { + return hubsoftTicketsRepo.getTicketsByTipo({ + tipoAtendimento: TYPES.PORTABILIDADE, + usuariosResponsaveisIds: parseCsvNumberEnv( + process.env.HUBSOFT_SUPORTE_USER_ID, + [142] + ), + lookbackDays: RESPONSAVEL_LOOKBACK_DAYS, + watermark + }); +} + +async function getConsultaBaseAtivaTickets(watermark) { + return hubsoftTicketsRepo.getTicketsByTipo({ + tipoAtendimento: TYPES.CONSULTA_BASE_ATIVA, + usuariosResponsaveisIds: parseCsvNumberEnv( + process.env.HUBSOFT_SUPORTE_USER_ID, [142] ), lookbackDays: RESPONSAVEL_LOOKBACK_DAYS, @@ -177,7 +241,11 @@ module.exports = { getCancelamentoTickets, getSacTickets, getTrocaTTickets, - + getUpgradeTickets, + getDowngradeTickets, + getMudancaEnderecoTickets, + getPortabilidadeTickets, + getConsultaBaseAtivaTickets, // hubglpi insertTicketsHubGlpi, insertSyncDataByIds, diff --git a/src/modules/tickets/services/consultaBaseAtiva.service.js b/src/modules/tickets/services/consultaBaseAtiva.service.js new file mode 100644 index 0000000..21d6314 --- /dev/null +++ b/src/modules/tickets/services/consultaBaseAtiva.service.js @@ -0,0 +1,43 @@ +// src/modules/tickets/services/consultaBaseAtiva.service.js + +const repository = require('../repositories/ticket.repository.js') +const modelHubGlpi = require('../models/hubglpi/model.js') +const ticketEntityResolver = require('./resolveTicketEntity.service.js') +const ttmodel = require('../models/glpi/consultaBaseAtiva.model.js') +const { logInfo, logError } = require('../../../shared/utils/logger.js') + +async function fetchNew(watermark) { + logInfo('[CONSULTA_BASE_ATIVA] Coletando novos chamados') + const raw = await repository.getConsultaBaseAtivaTickets(watermark) + return raw.map(t => modelHubGlpi.fromHubsoft(t, 'CONSULTA_BASE_ATIVA')) +} + +async function saveHubGlpi(tickets) { + if (!tickets.length) return + logInfo('[CONSULTA_BASE_ATIVA] Salvando tickets no HubGLPI') + await repository.insertTicketsHubGlpi(tickets) + await repository.insertSyncDataByIds(tickets.map(t => t.id_atendimento)) +} + +async function sendToGlpi(ticket) { + logInfo(`[CONSULTA_BASE_ATIVA] Enviando ticket ${ticket.id_atendimento} para GLPI`) + try { + const resolved = await ticketEntityResolver.resolveEntityId(ticket) + const payload = ttmodel.toGlpiPayload(resolved) + + const glpiId = await repository.insertTicketGlpi(payload) + await repository.insertGroupTicket(glpiId, 'CONSULTA_BASE_ATIVA') + await repository.updateSyncDataCreated(ticket.id_atendimento, glpiId) + + return glpiId + } catch (err) { + logError(err, `[CONSULTA_BASE_ATIVA] Erro ao enviar ticket ${ticket.id_atendimento}`) + throw err + } +} + +module.exports = { + fetchNew, + saveHubGlpi, + sendToGlpi +} diff --git a/src/modules/tickets/services/downgrade.service.js b/src/modules/tickets/services/downgrade.service.js new file mode 100644 index 0000000..3e8f391 --- /dev/null +++ b/src/modules/tickets/services/downgrade.service.js @@ -0,0 +1,43 @@ +// src/modules/tickets/services/downgrade.service.js + +const repository = require('../repositories/ticket.repository.js') +const modelHubGlpi = require('../models/hubglpi/model.js') +const ticketEntityResolver = require('./resolveTicketEntity.service.js') +const ttmodel = require('../models/glpi/downgrade.model.js') +const { logInfo, logError } = require('../../../shared/utils/logger.js') + +async function fetchNew(watermark) { + logInfo('[DOWNGRADE] Coletando novos chamados') + const raw = await repository.getDowngradeTickets(watermark) + return raw.map(t => modelHubGlpi.fromHubsoft(t, 'DOWNGRADE')) +} + +async function saveHubGlpi(tickets) { + if (!tickets.length) return + logInfo('[DOWNGRADE] Salvando tickets no HubGLPI') + await repository.insertTicketsHubGlpi(tickets) + await repository.insertSyncDataByIds(tickets.map(t => t.id_atendimento)) +} + +async function sendToGlpi(ticket) { + logInfo(`[DOWNGRADE] Enviando ticket ${ticket.id_atendimento} para GLPI`) + try { + const resolved = await ticketEntityResolver.resolveEntityId(ticket) + const payload = ttmodel.toGlpiPayload(resolved) + + const glpiId = await repository.insertTicketGlpi(payload) + await repository.insertGroupTicket(glpiId, 'DOWNGRADE') + await repository.updateSyncDataCreated(ticket.id_atendimento, glpiId) + + return glpiId + } catch (err) { + logError(err, `[DOWNGRADE] Erro ao enviar ticket ${ticket.id_atendimento}`) + throw err + } +} + +module.exports = { + fetchNew, + saveHubGlpi, + sendToGlpi +} diff --git a/src/modules/tickets/services/mudancaEndereco.service.js b/src/modules/tickets/services/mudancaEndereco.service.js new file mode 100644 index 0000000..dc24904 --- /dev/null +++ b/src/modules/tickets/services/mudancaEndereco.service.js @@ -0,0 +1,43 @@ +// src/modules/tickets/services/mudancaEndereco.service.js + +const repository = require('../repositories/ticket.repository.js') +const modelHubGlpi = require('../models/hubglpi/model.js') +const ticketEntityResolver = require('./resolveTicketEntity.service.js') +const ttmodel = require('../models/glpi/mudancaEndereco.model.js') +const { logInfo, logError } = require('../../../shared/utils/logger.js') + +async function fetchNew(watermark) { + logInfo('[MUDANCA_ENDERECO] Coletando novos chamados') + const raw = await repository.getMudancaEnderecoTickets(watermark) + return raw.map(t => modelHubGlpi.fromHubsoft(t, 'MUDANCA_ENDERECO')) +} + +async function saveHubGlpi(tickets) { + if (!tickets.length) return + logInfo('[MUDANCA_ENDERECO] Salvando tickets no HubGLPI') + await repository.insertTicketsHubGlpi(tickets) + await repository.insertSyncDataByIds(tickets.map(t => t.id_atendimento)) +} + +async function sendToGlpi(ticket) { + logInfo(`[MUDANCA_ENDERECO] Enviando ticket ${ticket.id_atendimento} para GLPI`) + try { + const resolved = await ticketEntityResolver.resolveEntityId(ticket) + const payload = ttmodel.toGlpiPayload(resolved) + + const glpiId = await repository.insertTicketGlpi(payload) + await repository.insertGroupTicket(glpiId, 'MUDANCA_ENDERECO') + await repository.updateSyncDataCreated(ticket.id_atendimento, glpiId) + + return glpiId + } catch (err) { + logError(err, `[MUDANCA_ENDERECO] Erro ao enviar ticket ${ticket.id_atendimento}`) + throw err + } +} + +module.exports = { + fetchNew, + saveHubGlpi, + sendToGlpi +} diff --git a/src/modules/tickets/services/portabilidade.service.js b/src/modules/tickets/services/portabilidade.service.js new file mode 100644 index 0000000..05dea62 --- /dev/null +++ b/src/modules/tickets/services/portabilidade.service.js @@ -0,0 +1,43 @@ +// src/modules/tickets/services/portabilidade.service.js + +const repository = require('../repositories/ticket.repository.js') +const modelHubGlpi = require('../models/hubglpi/model.js') +const ticketEntityResolver = require('./resolveTicketEntity.service.js') +const ttmodel = require('../models/glpi/portabilidade.model.js') +const { logInfo, logError } = require('../../../shared/utils/logger.js') + +async function fetchNew(watermark) { + logInfo('[PORTABILIDADE] Coletando novos chamados') + const raw = await repository.getPortabilidadeTickets(watermark) + return raw.map(t => modelHubGlpi.fromHubsoft(t, 'PORTABILIDADE')) +} + +async function saveHubGlpi(tickets) { + if (!tickets.length) return + logInfo('[PORTABILIDADE] Salvando tickets no HubGLPI') + await repository.insertTicketsHubGlpi(tickets) + await repository.insertSyncDataByIds(tickets.map(t => t.id_atendimento)) +} + +async function sendToGlpi(ticket) { + logInfo(`[PORTABILIDADE] Enviando ticket ${ticket.id_atendimento} para GLPI`) + try { + const resolved = await ticketEntityResolver.resolveEntityId(ticket) + const payload = ttmodel.toGlpiPayload(resolved) + + const glpiId = await repository.insertTicketGlpi(payload) + await repository.insertGroupTicket(glpiId, 'PORTABILIDADE') + await repository.updateSyncDataCreated(ticket.id_atendimento, glpiId) + + return glpiId + } catch (err) { + logError(err, `[PORTABILIDADE] Erro ao enviar ticket ${ticket.id_atendimento}`) + throw err + } +} + +module.exports = { + fetchNew, + saveHubGlpi, + sendToGlpi +} diff --git a/src/modules/tickets/services/upgrade.service.js b/src/modules/tickets/services/upgrade.service.js new file mode 100644 index 0000000..7f24b94 --- /dev/null +++ b/src/modules/tickets/services/upgrade.service.js @@ -0,0 +1,43 @@ +// src/modules/tickets/services/upgrade.service.js + +const repository = require('../repositories/ticket.repository.js') +const modelHubGlpi = require('../models/hubglpi/model.js') +const ticketEntityResolver = require('./resolveTicketEntity.service.js') +const ttmodel = require('../models/glpi/upgrade.model.js') +const { logInfo, logError } = require('../../../shared/utils/logger.js') + +async function fetchNew(watermark) { + logInfo('[UPGRADE] Coletando novos chamados') + const raw = await repository.getUpgradeTickets(watermark) + return raw.map(t => modelHubGlpi.fromHubsoft(t, 'UPGRADE')) +} + +async function saveHubGlpi(tickets) { + if (!tickets.length) return + logInfo('[UPGRADE] Salvando tickets no HubGLPI') + await repository.insertTicketsHubGlpi(tickets) + await repository.insertSyncDataByIds(tickets.map(t => t.id_atendimento)) +} + +async function sendToGlpi(ticket) { + logInfo(`[UPGRADE] Enviando ticket ${ticket.id_atendimento} para GLPI`) + try { + const resolved = await ticketEntityResolver.resolveEntityId(ticket) + const payload = ttmodel.toGlpiPayload(resolved) + + const glpiId = await repository.insertTicketGlpi(payload) + await repository.insertGroupTicket(glpiId, 'UPGRADE') + await repository.updateSyncDataCreated(ticket.id_atendimento, glpiId) + + return glpiId + } catch (err) { + logError(err, `[UPGRADE] Erro ao enviar ticket ${ticket.id_atendimento}`) + throw err + } +} + +module.exports = { + fetchNew, + saveHubGlpi, + sendToGlpi +} diff --git a/src/modules/tickets/useCases/syncTickets.usecase.js b/src/modules/tickets/useCases/syncTickets.usecase.js index 4b40019..8ea43c6 100644 --- a/src/modules/tickets/useCases/syncTickets.usecase.js +++ b/src/modules/tickets/useCases/syncTickets.usecase.js @@ -7,6 +7,11 @@ const implantacaoService = require('../services/implantacao.service.js') const cancelamentoService = require('../services/cancelamento.service.js') //const sacService = require('../services/sac.service.js') //TODO const trocaTitularidadeService = require('../services/trocaTitularidade.service.js') //TODO +const upgradeService = require('../services/upgrade.service.js') +const downgradeService = require('../services/downgrade.service.js') +const mudancaEnderecoService = require('../services/mudancaEndereco.service.js') +const portabilidadeService = require('../services/portabilidade.service.js') +const consultaBaseAtivaService = require('../services/consultaBaseAtiva.service.js') const ticketShared = require('../services/createTickets.service.js') const { logInfo, logError } = require('../../../shared/utils/logger.js') @@ -34,19 +39,44 @@ async function syncTicketsUseCase() { const trocaTitularidade = await trocaTitularidadeService.fetchNew(waterMark) logInfo(`[USECASE] ${trocaTitularidade.length} tickets Troca de Titularidade encontrados`) + const upgrade = await upgradeService.fetchNew(waterMark) + logInfo(`[USECASE] ${upgrade.length} tickets Upgrade encontrados`) + + const downgrade = await downgradeService.fetchNew(waterMark) + logInfo(`[USECASE] ${downgrade.length} tickets Downgrade encontrados`) + + const mudancaEndereco = await mudancaEnderecoService.fetchNew(waterMark) + logInfo(`[USECASE] ${mudancaEndereco.length} tickets Mudança de Endereço encontrados`) + + const portabilidade = await portabilidadeService.fetchNew(waterMark) + logInfo(`[USECASE] ${portabilidade.length} tickets Portabilidade encontrados`) + + const consultaBaseAtiva = await consultaBaseAtivaService.fetchNew(waterMark) + logInfo(`[USECASE] ${consultaBaseAtiva.length} tickets Consulta Base Ativa encontrados`) + await mundialeService.saveHubGlpi(mundiale) await implantacaoService.saveHubGlpi(implantacao) await cancelamentoService.saveHubGlpi(cancelamento) //await sacService.saveHubGlpi(sac) //TODO await trocaTitularidadeService.saveHubGlpi(trocaTitularidade) + await upgradeService.saveHubGlpi(upgrade) + await downgradeService.saveHubGlpi(downgrade) + await mudancaEnderecoService.saveHubGlpi(mudancaEndereco) + await portabilidadeService.saveHubGlpi(portabilidade) + await consultaBaseAtivaService.saveHubGlpi(consultaBaseAtiva) const allFetchedTickets = [ ...mundiale, ...implantacao, ...cancelamento, //...sac, - ...trocaTitularidade + ...trocaTitularidade, + ...upgrade, + ...downgrade, + ...mudancaEndereco, + ...portabilidade, + ...consultaBaseAtiva ] const newWaterMark = resolveNewWatermark(allFetchedTickets, waterMark) @@ -86,7 +116,12 @@ function resolveTicketService(type) { IMPLANTACAO: implantacaoService, CANCELAMENTO: cancelamentoService, //SAC: sacService, //TODO - TITULARIDADE: trocaTitularidadeService + TITULARIDADE: trocaTitularidadeService, + UPGRADE: upgradeService, + DOWNGRADE: downgradeService, + MUDANCA_ENDERECO: mudancaEnderecoService, + PORTABILIDADE: portabilidadeService, + CONSULTA_BASE_ATIVA: consultaBaseAtivaService } return map[type]