"REFACTOR: API refatorada para se adequar a nova arquitetura baseada em Clean Architeture"
This commit is contained in:
parent
5adc1dba38
commit
038b9eb3d4
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
.env
|
.env*
|
||||||
node_modules/
|
node_modules/
|
||||||
|
logs/
|
||||||
773
package-lock.json
generated
773
package-lock.json
generated
@ -1,20 +1,71 @@
|
|||||||
{
|
{
|
||||||
"name": "sothiscontratacaoapi",
|
"name": "node-clean-architecture-starter",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "sothiscontratacaoapi",
|
"name": "node-clean-architecture-starter",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.6.0",
|
"axios": "^1.6.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
|
"dotenv": "^17.2.3",
|
||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
"qs": "^6.11.0"
|
"node-cron": "^4.2.1",
|
||||||
|
"qs": "^6.11.0",
|
||||||
|
"winston": "^3.18.3",
|
||||||
|
"winston-daily-rotate-file": "^5.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"cross-env": "^10.1.0",
|
||||||
|
"nodemon": "^3.1.11"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@colors/colors": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.1.90"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@dabh/diagnostics": {
|
||||||
|
"version": "2.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.8.tgz",
|
||||||
|
"integrity": "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@so-ric/colorspace": "^1.1.6",
|
||||||
|
"enabled": "2.0.x",
|
||||||
|
"kuler": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@epic-web/invariant": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@so-ric/colorspace": {
|
||||||
|
"version": "1.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@so-ric/colorspace/-/colorspace-1.1.6.tgz",
|
||||||
|
"integrity": "sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"color": "^5.0.2",
|
||||||
|
"text-hex": "1.0.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/triple-beam": {
|
||||||
|
"version": "1.3.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz",
|
||||||
|
"integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/accepts": {
|
"node_modules/accepts": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
|
||||||
@ -28,6 +79,26 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/anymatch": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
|
||||||
|
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"normalize-path": "^3.0.0",
|
||||||
|
"picomatch": "^2.0.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/async": {
|
||||||
|
"version": "3.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
|
||||||
|
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/asynckit": {
|
"node_modules/asynckit": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
@ -45,6 +116,26 @@
|
|||||||
"proxy-from-env": "^1.1.0"
|
"proxy-from-env": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/balanced-match": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/binary-extensions": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
||||||
|
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/body-parser": {
|
"node_modules/body-parser": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
|
||||||
@ -65,6 +156,30 @@
|
|||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": "^1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/braces": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fill-range": "^7.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/bytes": {
|
"node_modules/bytes": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
@ -103,6 +218,77 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/chokidar": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"anymatch": "~3.1.2",
|
||||||
|
"braces": "~3.0.2",
|
||||||
|
"glob-parent": "~5.1.2",
|
||||||
|
"is-binary-path": "~2.1.0",
|
||||||
|
"is-glob": "~4.0.1",
|
||||||
|
"normalize-path": "~3.0.0",
|
||||||
|
"readdirp": "~3.6.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8.10.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"fsevents": "~2.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color": {
|
||||||
|
"version": "5.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color/-/color-5.0.3.tgz",
|
||||||
|
"integrity": "sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^3.1.3",
|
||||||
|
"color-string": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color-convert": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-3.1.3.tgz",
|
||||||
|
"integrity": "sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color-name": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.20"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color-string": {
|
||||||
|
"version": "2.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-string/-/color-string-2.1.4.tgz",
|
||||||
|
"integrity": "sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/combined-stream": {
|
"node_modules/combined-stream": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
@ -115,6 +301,13 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/concat-map": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/content-disposition": {
|
"node_modules/content-disposition": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
|
||||||
@ -167,6 +360,39 @@
|
|||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cross-env": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@epic-web/invariant": "^1.0.0",
|
||||||
|
"cross-spawn": "^7.0.6"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"cross-env": "dist/bin/cross-env.js",
|
||||||
|
"cross-env-shell": "dist/bin/cross-env-shell.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cross-spawn": {
|
||||||
|
"version": "7.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
|
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"path-key": "^3.1.0",
|
||||||
|
"shebang-command": "^2.0.0",
|
||||||
|
"which": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.4.3",
|
"version": "4.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||||
@ -202,6 +428,18 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dotenv": {
|
||||||
|
"version": "17.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz",
|
||||||
|
"integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==",
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://dotenvx.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dunder-proto": {
|
"node_modules/dunder-proto": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||||
@ -222,6 +460,12 @@
|
|||||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
|
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/enabled": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/encodeurl": {
|
"node_modules/encodeurl": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||||
@ -333,6 +577,34 @@
|
|||||||
"url": "https://opencollective.com/express"
|
"url": "https://opencollective.com/express"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fecha": {
|
||||||
|
"version": "4.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
|
||||||
|
"integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/file-stream-rotator": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz",
|
||||||
|
"integrity": "sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"moment": "^2.29.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fill-range": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"to-regex-range": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/finalhandler": {
|
"node_modules/finalhandler": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
|
||||||
@ -350,6 +622,12 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fn.name": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/follow-redirects": {
|
"node_modules/follow-redirects": {
|
||||||
"version": "1.15.11",
|
"version": "1.15.11",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
||||||
@ -425,6 +703,21 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fsevents": {
|
||||||
|
"version": "2.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||||
|
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/function-bind": {
|
"node_modules/function-bind": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||||
@ -471,6 +764,19 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/glob-parent": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"is-glob": "^4.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/gopd": {
|
"node_modules/gopd": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||||
@ -483,6 +789,16 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/has-flag": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/has-symbols": {
|
"node_modules/has-symbols": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||||
@ -559,6 +875,13 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ignore-by-default": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/inherits": {
|
"node_modules/inherits": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
@ -574,12 +897,100 @@
|
|||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-binary-path": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"binary-extensions": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-extglob": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-glob": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-extglob": "^2.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-number": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-promise": {
|
"node_modules/is-promise": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
|
||||||
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
|
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/is-stream": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/isexe": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/kuler": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/logform": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@colors/colors": "1.6.0",
|
||||||
|
"@types/triple-beam": "^1.3.2",
|
||||||
|
"fecha": "^4.2.0",
|
||||||
|
"ms": "^2.1.1",
|
||||||
|
"safe-stable-stringify": "^2.3.1",
|
||||||
|
"triple-beam": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/math-intrinsics": {
|
"node_modules/math-intrinsics": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||||
@ -631,6 +1042,28 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/minimatch": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^1.1.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/moment": {
|
||||||
|
"version": "2.30.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
|
||||||
|
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
@ -646,6 +1079,54 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/node-cron": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-cron/-/node-cron-4.2.1.tgz",
|
||||||
|
"integrity": "sha512-lgimEHPE/QDgFlywTd8yTR61ptugX3Qer29efeyWw2rv259HtGBNn1vZVmp8lB9uo9wC0t/AT4iGqXxia+CJFg==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/nodemon": {
|
||||||
|
"version": "3.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.11.tgz",
|
||||||
|
"integrity": "sha512-is96t8F/1//UHAjNPHpbsNY46ELPpftGUoSVNXwUfMk/qdjSylYrWSu1XavVTBOn526kFiOR733ATgNBCQyH0g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"chokidar": "^3.5.2",
|
||||||
|
"debug": "^4",
|
||||||
|
"ignore-by-default": "^1.0.1",
|
||||||
|
"minimatch": "^3.1.2",
|
||||||
|
"pstree.remy": "^1.1.8",
|
||||||
|
"semver": "^7.5.3",
|
||||||
|
"simple-update-notifier": "^2.0.0",
|
||||||
|
"supports-color": "^5.5.0",
|
||||||
|
"touch": "^3.1.0",
|
||||||
|
"undefsafe": "^2.0.5"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"nodemon": "bin/nodemon.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/nodemon"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/normalize-path": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-assign": {
|
"node_modules/object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
@ -655,6 +1136,15 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/object-hash": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-inspect": {
|
"node_modules/object-inspect": {
|
||||||
"version": "1.13.4",
|
"version": "1.13.4",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
||||||
@ -688,6 +1178,15 @@
|
|||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/one-time": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fn.name": "1.x.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/parseurl": {
|
"node_modules/parseurl": {
|
||||||
"version": "1.3.3",
|
"version": "1.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||||
@ -697,6 +1196,16 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/path-key": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/path-to-regexp": {
|
"node_modules/path-to-regexp": {
|
||||||
"version": "8.3.0",
|
"version": "8.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
|
||||||
@ -707,6 +1216,19 @@
|
|||||||
"url": "https://opencollective.com/express"
|
"url": "https://opencollective.com/express"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/picomatch": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/proxy-addr": {
|
"node_modules/proxy-addr": {
|
||||||
"version": "2.0.7",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||||
@ -726,6 +1248,13 @@
|
|||||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/pstree.remy": {
|
||||||
|
"version": "1.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
|
||||||
|
"integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/qs": {
|
"node_modules/qs": {
|
||||||
"version": "6.14.0",
|
"version": "6.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
|
||||||
@ -781,6 +1310,33 @@
|
|||||||
"url": "https://opencollective.com/express"
|
"url": "https://opencollective.com/express"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/readable-stream": {
|
||||||
|
"version": "3.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||||
|
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/readdirp": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"picomatch": "^2.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/router": {
|
"node_modules/router": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
|
||||||
@ -817,12 +1373,34 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/safe-stable-stringify": {
|
||||||
|
"version": "2.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
|
||||||
|
"integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/safer-buffer": {
|
"node_modules/safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/semver": {
|
||||||
|
"version": "7.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
||||||
|
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/send": {
|
"node_modules/send": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
|
||||||
@ -866,6 +1444,29 @@
|
|||||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/shebang-command": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"shebang-regex": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/shebang-regex": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/side-channel": {
|
"node_modules/side-channel": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
||||||
@ -938,6 +1539,28 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/simple-update-notifier": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"semver": "^7.5.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/stack-trace": {
|
||||||
|
"version": "0.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
|
||||||
|
"integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/statuses": {
|
"node_modules/statuses": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
||||||
@ -947,6 +1570,47 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/string_decoder": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "~5.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/supports-color": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"has-flag": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/text-hex": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/to-regex-range": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-number": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/toidentifier": {
|
"node_modules/toidentifier": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
@ -956,6 +1620,25 @@
|
|||||||
"node": ">=0.6"
|
"node": ">=0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/touch": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"bin": {
|
||||||
|
"nodetouch": "bin/nodetouch.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/triple-beam": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/type-is": {
|
"node_modules/type-is": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
|
||||||
@ -970,6 +1653,13 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/undefsafe": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/unpipe": {
|
"node_modules/unpipe": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
@ -979,6 +1669,12 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/util-deprecate": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/vary": {
|
"node_modules/vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
@ -988,6 +1684,77 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/which": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"isexe": "^2.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"node-which": "bin/node-which"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/winston": {
|
||||||
|
"version": "3.18.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/winston/-/winston-3.18.3.tgz",
|
||||||
|
"integrity": "sha512-NoBZauFNNWENgsnC9YpgyYwOVrl2m58PpQ8lNHjV3kosGs7KJ7Npk9pCUE+WJlawVSe8mykWDKWFSVfs3QO9ww==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@colors/colors": "^1.6.0",
|
||||||
|
"@dabh/diagnostics": "^2.0.8",
|
||||||
|
"async": "^3.2.3",
|
||||||
|
"is-stream": "^2.0.0",
|
||||||
|
"logform": "^2.7.0",
|
||||||
|
"one-time": "^1.0.0",
|
||||||
|
"readable-stream": "^3.4.0",
|
||||||
|
"safe-stable-stringify": "^2.3.1",
|
||||||
|
"stack-trace": "0.0.x",
|
||||||
|
"triple-beam": "^1.3.0",
|
||||||
|
"winston-transport": "^4.9.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/winston-daily-rotate-file": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-JDjiXXkM5qvwY06733vf09I2wnMXpZEhxEVOSPenZMii+g7pcDcTBt2MRugnoi8BwVSuCT2jfRXBUy+n1Zz/Yw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"file-stream-rotator": "^0.6.1",
|
||||||
|
"object-hash": "^3.0.0",
|
||||||
|
"triple-beam": "^1.4.1",
|
||||||
|
"winston-transport": "^4.7.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"winston": "^3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/winston-transport": {
|
||||||
|
"version": "4.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz",
|
||||||
|
"integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"logform": "^2.7.0",
|
||||||
|
"readable-stream": "^3.6.2",
|
||||||
|
"triple-beam": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/wrappy": {
|
"node_modules/wrappy": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
|
|||||||
27
package.json
27
package.json
@ -1,10 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "sothiscontratacaoapi",
|
"name": "node-clean-architecture-starter",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"main": "server.js",
|
"main": "src/app.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"start:api": "cross-env NODE_ENV=production node src/app.js",
|
||||||
"start": "node server.js"
|
"dev:api": "cross-env NODE_ENV=development nodemon src/app.js",
|
||||||
|
"start:worker": "cross-env NODE_ENV=production node src/worker.js",
|
||||||
|
"dev:worker": "cross-env NODE_ENV=development nodemon src/worker.js",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -13,12 +16,20 @@
|
|||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"description": "",
|
"description": "A robust and scalable Node.js project starter based on Clean Architecture principles.",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"axios": "^1.6.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
|
"dotenv": "^17.2.3",
|
||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
|
"node-cron": "^4.2.1",
|
||||||
"qs": "^6.11.0",
|
"qs": "^6.11.0",
|
||||||
"axios": "^1.6.0"
|
"winston": "^3.18.3",
|
||||||
|
"winston-daily-rotate-file": "^5.0.0"
|
||||||
|
},
|
||||||
|
"type": "commonjs",
|
||||||
|
"devDependencies": {
|
||||||
|
"cross-env": "^10.1.0",
|
||||||
|
"nodemon": "^3.1.11"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
const app = require('./src/app.js');
|
|
||||||
const port = process.env.PORT || 3000;
|
|
||||||
|
|
||||||
app.listen(port, () => {
|
|
||||||
console.log(`Server is running on port ${port}`);
|
|
||||||
});
|
|
||||||
31
src/app.js
31
src/app.js
@ -1,11 +1,36 @@
|
|||||||
|
// Ponto de entrada para a API
|
||||||
|
const loadEnv = require('./shared/config/environment.js');
|
||||||
|
loadEnv();
|
||||||
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const routes = require('./routes/routes.js');
|
|
||||||
const cors = require('cors');
|
const cors = require('cors');
|
||||||
|
const routes = require('./routes/routes.js');
|
||||||
|
const logger = require('./shared/utils/logger.js');
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
const PORT = process.env.PORT || 3000;
|
||||||
|
|
||||||
app.use(express.json());
|
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
|
app.use(express.json());
|
||||||
app.use('/api', routes);
|
app.use('/api', routes);
|
||||||
|
|
||||||
module.exports = app;
|
app.listen(PORT, () => {
|
||||||
|
logger.info(`🚀 Servidor API rodando na porta ${PORT} em modo ${process.env.NODE_ENV}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
DESCRIÇÃO:
|
||||||
|
Este arquivo é o ponto de entrada principal (entry point) da aplicação. Ele é responsável por inicializar e configurar o servidor Express.
|
||||||
|
|
||||||
|
FLUXO:
|
||||||
|
1. Carrega as variáveis de ambiente a partir do arquivo `.env` utilizando a função `loadEnv`.
|
||||||
|
2. Importa as dependências necessárias, como o `express` para o servidor, `routes` para o roteamento e `logger` para os logs.
|
||||||
|
3. Cria uma instância do aplicativo Express.
|
||||||
|
4. Define a porta do servidor, utilizando a variável de ambiente `PORT` ou o valor padrão `3000`.
|
||||||
|
5. Configura o middleware `express.json()` para permitir que a API aceite e interprete corpos de requisição no formato JSON.
|
||||||
|
6. Associa as rotas importadas de `./routes/routes.js` ao prefixo `/api`. Todas as rotas definidas nesse arquivo serão acessíveis a partir de `/api/...`.
|
||||||
|
7. Inicia o servidor para escutar na porta definida.
|
||||||
|
8. Registra um log informativo quando o servidor é iniciado com sucesso, indicando a porta e o ambiente de execução (`development`, `production`, etc.).
|
||||||
|
|
||||||
|
Este arquivo é o coração da API, orquestrando a configuração inicial e o roteamento de todas as requisições recebidas.
|
||||||
|
*/
|
||||||
@ -1,34 +0,0 @@
|
|||||||
const dotenv = require("dotenv");
|
|
||||||
dotenv.config();
|
|
||||||
|
|
||||||
// Google API Key
|
|
||||||
const googleApiKey = process.env.GOOGLE_API_KEY;
|
|
||||||
|
|
||||||
// Geogrid API Configs
|
|
||||||
const geogridApiUrl = process.env.GEOGRID_API_URL;
|
|
||||||
const geogridApiKey = process.env.GEOGRID_API_KEY;
|
|
||||||
const geogridApiCookie = process.env.GEOGRID_API_COOKIE;
|
|
||||||
|
|
||||||
// Hubsoft API Configs
|
|
||||||
const hubsoftUrl = process.env.HUBSOFT_URL;
|
|
||||||
const hubsoftAuthUrl = `${process.env.HUBSOFT_URL}oauth/token`;
|
|
||||||
const hubsoftClientId = process.env.HUBSOFT_CLIENT_ID;
|
|
||||||
const hubsoftClientSecret = process.env.HUBSOFT_CLIENT_SECRET;
|
|
||||||
const hubsoftUsername = process.env.HUBSOFT_USERNAME;
|
|
||||||
const hubsoftPassword = process.env.HUBSOFT_PASSWORD;
|
|
||||||
const hubsoftGrantType = process.env.HUBSOFT_GRANT_TYPE;
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
googleApiKey: googleApiKey,
|
|
||||||
geogridApiUrl: geogridApiUrl,
|
|
||||||
geogridApiKey: geogridApiKey,
|
|
||||||
geogridApiCookie: geogridApiCookie,
|
|
||||||
hubsoftUrl: hubsoftUrl,
|
|
||||||
|
|
||||||
hubsoftAuthUrl: hubsoftAuthUrl,
|
|
||||||
hubsoftClientId: hubsoftClientId,
|
|
||||||
hubsoftClientSecret: hubsoftClientSecret,
|
|
||||||
hubsoftUsername: hubsoftUsername,
|
|
||||||
hubsoftPassword: hubsoftPassword,
|
|
||||||
hubsoftGrantType: hubsoftGrantType
|
|
||||||
};
|
|
||||||
@ -1,96 +0,0 @@
|
|||||||
const geogridService = require("../services/geogridService.js");
|
|
||||||
const googleService = require("../services/googleService.js");
|
|
||||||
const cepRestService = require("../services/cepRestService.js");
|
|
||||||
const hubsoftService = require("../services/hubsoftService.js");
|
|
||||||
|
|
||||||
async function handleViabilidade(req, res) {
|
|
||||||
const rawCep = req.body.cep;
|
|
||||||
const rawNumero = req.body.numero;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!rawCep && !rawNumero) return res.status(400).json({ error: 'cep e número são obrigatórios' });
|
|
||||||
if (!rawCep) return res.status(400).json({ error: 'cep é obrigatório' });
|
|
||||||
if (!rawNumero) return res.status(400).json({ error: 'número é obrigatório' });
|
|
||||||
|
|
||||||
// Consulta o endereço completo usando o serviço de CEP
|
|
||||||
|
|
||||||
const address = await cepRestService.getConsultaCep(rawCep, rawNumero);
|
|
||||||
|
|
||||||
if (!address) return res.status(404).json({ error: 'Endereço não encontrado para o CEP fornecido' });
|
|
||||||
|
|
||||||
const city = address.data[`cep:${rawCep}`].localidade;
|
|
||||||
const state = address.data[`cep:${rawCep}`].uf;
|
|
||||||
const numero = rawNumero;
|
|
||||||
|
|
||||||
const addressString = `${address.data[`cep:${rawCep}`].logradouro}, ${numero}, ${address.data[`cep:${rawCep}`].bairro}, ${city}, ${state}, ${address.data[`cep:${rawCep}`].cep}`;
|
|
||||||
|
|
||||||
// Obtém as coordenadas usando o serviço do Google
|
|
||||||
|
|
||||||
const coords = await googleService.geocodeWithGoogle(addressString);
|
|
||||||
if (!coords) return res.status(500).json({ error: 'Não foi possível obter as coordenadas do endereço' });
|
|
||||||
|
|
||||||
// Consulta a viabilidade no geogridService
|
|
||||||
|
|
||||||
const viabilidade = await geogridService.consultaViabilidade(coords.lat, coords.lon);
|
|
||||||
|
|
||||||
let naoDedicado;
|
|
||||||
let dedicado;
|
|
||||||
|
|
||||||
// Lógica para determinar os valores de naoDedicado e dedicado com base na distância
|
|
||||||
|
|
||||||
if (viabilidade.data) {
|
|
||||||
const distancia = viabilidade.data.distancia;
|
|
||||||
if (distancia <= 500) {
|
|
||||||
naoDedicado = true;
|
|
||||||
dedicado = true;
|
|
||||||
} else if (distancia <= 1000) {
|
|
||||||
naoDedicado = true;
|
|
||||||
dedicado = false;
|
|
||||||
} else {
|
|
||||||
naoDedicado = false;
|
|
||||||
dedicado = false;
|
|
||||||
} } else {
|
|
||||||
naoDedicado = false;
|
|
||||||
dedicado = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retorna a resposta com os dados necessários
|
|
||||||
|
|
||||||
return res.json({
|
|
||||||
bairro: address.data[`cep:${rawCep}`].bairro,
|
|
||||||
cidade: city,
|
|
||||||
estado: state,
|
|
||||||
logradouro: address.data[`cep:${rawCep}`].logradouro,
|
|
||||||
naoDedicado,
|
|
||||||
dedicado,
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Erro ao processar a viabilidade:", error);
|
|
||||||
return res.status(500).json({ error: "Erro ao processar a viabilidade" });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleCriarProspecto(req, res) {
|
|
||||||
|
|
||||||
const prospectData = req.body;
|
|
||||||
console.log("Dados recebidos para criação de prospecto:", prospectData);
|
|
||||||
try {
|
|
||||||
const resultado = await hubsoftService.criarProspectHubsoft(prospectData);
|
|
||||||
return res.json({ message: 'Prospecto criado com sucesso', data: resultado });
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Erro ao criar prospecto:", error);
|
|
||||||
return res.status(500).json({ error: "Erro ao criar prospecto" });
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// async function handleTeste(req, res) {
|
|
||||||
// console.log("Rota de teste acessada com sucesso.");
|
|
||||||
// return res.json({ message: "Rota de teste funcionando corretamente!" });
|
|
||||||
// }
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
handleViabilidade,
|
|
||||||
handleCriarProspecto
|
|
||||||
};
|
|
||||||
56
src/modules/contratacao/contratacao.controller.js
Normal file
56
src/modules/contratacao/contratacao.controller.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
const contratacaoService = require('./contratacao.service.js');
|
||||||
|
|
||||||
|
async function handleViabilidade(req, res) {
|
||||||
|
const { cep, numero } = req.body;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const resultadoViabilidade = await contratacaoService.verificarViabilidade(cep, numero);
|
||||||
|
return res.json(resultadoViabilidade);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erro no controller ao processar viabilidade:", error.message);
|
||||||
|
const statusCode = error.statusCode || 500;
|
||||||
|
return res.status(statusCode).json({ error: error.message || "Erro interno ao processar a viabilidade." });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleCriarProspecto(req, res) {
|
||||||
|
const prospectData = req.body;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const resultado = await contratacaoService.criarProspecto(prospectData);
|
||||||
|
return res.json({ message: 'Prospecto criado com sucesso', data: resultado });
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erro no controller ao criar prospecto:", error.message);
|
||||||
|
const statusCode = error.statusCode || 500;
|
||||||
|
return res.status(statusCode).json({ error: error.message || "Erro interno ao criar o prospecto." });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
handleViabilidade,
|
||||||
|
handleCriarProspecto
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
DESCRIÇÃO:
|
||||||
|
Este arquivo é o "Controller" do módulo de contratação. Ele atua como a camada intermediária que conecta as rotas da API com a lógica de negócio (serviços). Sua principal responsabilidade é receber as requisições HTTP, extrair os dados necessários (do corpo, parâmetros, etc.), chamar o serviço correspondente e formatar a resposta a ser enviada de volta ao cliente.
|
||||||
|
|
||||||
|
FUNÇÕES:
|
||||||
|
- handleViabilidade:
|
||||||
|
1. É acionado por uma rota (ex: POST /api/contratacao/viabilidade).
|
||||||
|
2. Extrai `cep` e `numero` do corpo da requisição (`req.body`).
|
||||||
|
3. Chama a função `verificarViabilidade` do `contratacao.service`, passando os dados recebidos.
|
||||||
|
4. Se a verificação for bem-sucedida, retorna o resultado como um JSON com status 200.
|
||||||
|
5. Se ocorrer um erro (lançado pelo serviço), captura o erro, loga a mensagem e retorna uma resposta de erro em JSON com o `statusCode` apropriado (ex: 400, 404, 500).
|
||||||
|
|
||||||
|
- handleCriarProspecto:
|
||||||
|
1. É acionado por uma rota (ex: POST /api/contratacao/prospecto).
|
||||||
|
2. Pega todos os dados do corpo da requisição (`req.body`), que representam os dados do prospecto.
|
||||||
|
3. Chama a função `criarProspecto` do `contratacao.service`.
|
||||||
|
4. Se a criação for bem-sucedida, retorna uma mensagem de sucesso com os dados do resultado.
|
||||||
|
5. Em caso de erro, segue um fluxo de tratamento de erro similar ao `handleViabilidade`.
|
||||||
|
|
||||||
|
Este controller garante que a lógica de negócio permaneça desacoplada do Express, focando apenas na orquestração do fluxo da requisição e resposta.
|
||||||
|
*/
|
||||||
13
src/modules/contratacao/contratacao.model.js
Normal file
13
src/modules/contratacao/contratacao.model.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
DESCRIÇÃO:
|
||||||
|
Este arquivo é destinado a definir o "Model" ou o esquema de dados para o módulo de contratação.
|
||||||
|
|
||||||
|
FLUXO:
|
||||||
|
- Em uma arquitetura com banco de dados, este arquivo normalmente conteria a definição de um modelo de dados usando um ORM (Object-Relational Mapper) como Sequelize (para SQL) ou Mongoose (para MongoDB).
|
||||||
|
- O modelo definiria os campos, tipos de dados, validações e relacionamentos para a entidade "contratação" ou "prospecto".
|
||||||
|
- Por exemplo, poderia definir que um prospecto deve ter campos como `nome` (String, obrigatório), `email` (String, formato de email), `cep` (String), etc.
|
||||||
|
- Este modelo seria então utilizado pelo `contratacao.repository.js` para realizar operações de CRUD (Create, Read, Update, Delete) no banco de dados de forma estruturada e segura.
|
||||||
|
|
||||||
|
ESTADO ATUAL:
|
||||||
|
Atualmente, o arquivo está como um placeholder e não contém uma implementação de modelo. A lógica de negócio não depende de uma estrutura de dados formalmente definida aqui.
|
||||||
|
*/
|
||||||
18
src/modules/contratacao/contratacao.repository.js
Normal file
18
src/modules/contratacao/contratacao.repository.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
DESCRIÇÃO:
|
||||||
|
Este arquivo implementa o padrão de "Repository" (Repositório) para o módulo de contratação. A camada de repositório é responsável por toda a comunicação com a fonte de dados, que geralmente é um banco de dados.
|
||||||
|
|
||||||
|
FLUXO:
|
||||||
|
1. Seria chamado pelo `contratacao.service.js` para persistir ou recuperar dados.
|
||||||
|
2. Utilizaria o `contratacao.model.js` para interagir com o banco de dados de forma estruturada. Por exemplo, usaria um modelo Sequelize ou Mongoose para executar queries.
|
||||||
|
3. Conteria métodos para operações de CRUD (Create, Read, Update, Delete), como:
|
||||||
|
- `create(prospectData)`: Para salvar um novo prospecto no banco de dados.
|
||||||
|
- `findById(id)`: Para buscar um prospecto pelo seu ID.
|
||||||
|
- `findAll()`: Para listar todos os prospectos.
|
||||||
|
- `update(id, newData)`: Para atualizar os dados de um prospecto.
|
||||||
|
- `delete(id)`: Para remover um prospecto.
|
||||||
|
4. Abstrairia os detalhes de implementação do banco de dados, permitindo que o serviço solicite os dados sem se preocupar em como eles são armazenados ou recuperados.
|
||||||
|
|
||||||
|
ESTADO ATUAL:
|
||||||
|
Atualmente, o arquivo é um placeholder. Como a lógica atual da aplicação se baseia em chamadas a APIs externas (Hubsoft) e não em um banco de dados local para prospectos, este repositório não tem uma implementação ativa. Se a aplicação precisasse armazenar dados localmente, este arquivo seria implementado.
|
||||||
|
*/
|
||||||
96
src/modules/contratacao/contratacao.service.js
Normal file
96
src/modules/contratacao/contratacao.service.js
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
const geogridService = require("../../shared/apis/geogridService.js");
|
||||||
|
const googleService = require("../../shared/apis/googleService.js");
|
||||||
|
const cepRestService = require("../../shared/apis/cepRestService.js");
|
||||||
|
const hubsoftService = require("../../shared/apis/hubsoftService.js");
|
||||||
|
|
||||||
|
class ServiceError extends Error {
|
||||||
|
constructor(message, statusCode = 500) {
|
||||||
|
super(message);
|
||||||
|
this.name = 'ServiceError';
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function verificarViabilidade(rawCep, rawNumero) {
|
||||||
|
if (!rawCep || !rawNumero) {
|
||||||
|
throw new ServiceError('CEP e número são obrigatórios.', 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const address = await cepRestService.getConsultaCep(rawCep, rawNumero);
|
||||||
|
if (!address || !address.success || !address.data) {
|
||||||
|
throw new ServiceError('Endereço não encontrado para o CEP fornecido.', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { logradouro, bairro, localidade: city, uf: state, cep } = address.data;
|
||||||
|
const addressString = `${logradouro}, ${rawNumero}, ${bairro}, ${city}, ${state}, ${cep}`;
|
||||||
|
|
||||||
|
const coords = await googleService.geocodeWithGoogle(addressString);
|
||||||
|
if (!coords) {
|
||||||
|
throw new ServiceError('Não foi possível obter as coordenadas do endereço.', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
const viabilidade = await geogridService.consultaViabilidade(coords.lat, coords.lon);
|
||||||
|
|
||||||
|
let naoDedicado = false;
|
||||||
|
let dedicado = false;
|
||||||
|
|
||||||
|
if (viabilidade.data) {
|
||||||
|
const distancia = viabilidade.data.distancia;
|
||||||
|
if (distancia <= 500) {
|
||||||
|
naoDedicado = true;
|
||||||
|
dedicado = true;
|
||||||
|
} else if (distancia <= 1000) {
|
||||||
|
naoDedicado = true;
|
||||||
|
dedicado = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
bairro,
|
||||||
|
cidade: city,
|
||||||
|
estado: state,
|
||||||
|
logradouro,
|
||||||
|
naoDedicado,
|
||||||
|
dedicado,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function criarProspecto(prospectData) {
|
||||||
|
try {
|
||||||
|
console.log("Service: Dados recebidos para criação de prospecto:", prospectData);
|
||||||
|
const resultado = await hubsoftService.criarProspectHubsoft(prospectData);
|
||||||
|
return resultado;
|
||||||
|
} catch (error) {
|
||||||
|
throw new ServiceError(error.message || 'Erro ao comunicar com o serviço de prospectos.', 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
verificarViabilidade,
|
||||||
|
criarProspecto
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
DESCRIÇÃO:
|
||||||
|
Este arquivo é a camada de "Serviço" para o módulo de contratação. Ele contém a lógica de negócio principal da aplicação, orquestrando chamadas a diferentes APIs externas e processando os dados para atender às solicitações do `contratacao.controller.js`.
|
||||||
|
|
||||||
|
A classe `ServiceError` é uma classe de erro personalizada para permitir que os serviços lancem exceções com `status codes` HTTP específicos, que podem ser capturados e tratados pelo controller.
|
||||||
|
|
||||||
|
FUNÇÕES:
|
||||||
|
- verificarViabilidade(rawCep, rawNumero):
|
||||||
|
1. É chamado pelo `contratacao.controller.js` com o CEP e o número do endereço.
|
||||||
|
2. Valida se o CEP e o número foram fornecidos, lançando um `ServiceError` (400) se não forem.
|
||||||
|
3. Chama o `cepRestService` para obter os dados do endereço a partir do CEP. Se não encontrar, lança um `ServiceError` (404).
|
||||||
|
4. Monta uma string de endereço completo e a utiliza para obter as coordenadas geográficas (latitude e longitude) através do `googleService`. Lança um erro (500) se não conseguir obter as coordenadas.
|
||||||
|
5. Com as coordenadas, chama o `geogridService` para consultar a viabilidade do serviço, que retorna a distância de um ponto de presença.
|
||||||
|
6. Com base na distância retornada pelo GeoGrid, define as flags `naoDedicado` e `dedicado` (ex: se a distância for menor que 500m, ambos são `true`).
|
||||||
|
7. Retorna um objeto contendo os dados do endereço e as flags de viabilidade para o controller.
|
||||||
|
|
||||||
|
- criarProspecto(prospectData):
|
||||||
|
1. Recebe os dados do prospecto do `contratacao.controller.js`.
|
||||||
|
2. Chama o `hubsoftService` para criar o prospecto no sistema Hubsoft.
|
||||||
|
3. Retorna o resultado da criação.
|
||||||
|
4. Em caso de erro na comunicação com o Hubsoft, lança um `ServiceError` (500).
|
||||||
|
|
||||||
|
Este serviço é o cérebro do módulo, conectando múltiplas fontes de dados externas para fornecer uma resposta unificada sobre a viabilidade e para registrar novos clientes.
|
||||||
|
*/
|
||||||
@ -1,14 +1,35 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const controller = require('../controllers/controller.js');
|
const contratacaoController = require('../modules/contratacao/contratacao.controller.js');
|
||||||
|
|
||||||
// Rota para consulta de viabilidade
|
// Rota para consulta de viabilidade
|
||||||
router.post('/viabilidade', controller.handleViabilidade);
|
router.post('/viabilidade', contratacaoController.handleViabilidade);
|
||||||
|
|
||||||
// Rota para criação de prospecto no Hubsoft
|
// Rota para criação de prospecto no Hubsoft
|
||||||
router.post('/prospecto', controller.handleCriarProspecto);
|
router.post('/prospecto', contratacaoController.handleCriarProspecto);
|
||||||
|
|
||||||
// router.post('/teste', controller.handleTeste);
|
// router.post('/teste', controller.handleTeste);
|
||||||
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
||||||
|
/*
|
||||||
|
DESCRIÇÃO:
|
||||||
|
Este arquivo é o roteador principal da aplicação. Ele é responsável por definir todos os endpoints (URLs) da API e associar cada um a uma função específica do controller correspondente.
|
||||||
|
|
||||||
|
FLUXO:
|
||||||
|
1. Este arquivo é carregado pelo `app.js`, que monta este roteador sob o prefixo `/api`. Isso significa que todas as rotas definidas aqui serão acessíveis a partir de `/api/...`.
|
||||||
|
2. Ele importa o `contratacao.controller.js`, que contém a lógica para manipular as requisições.
|
||||||
|
3. Define as seguintes rotas:
|
||||||
|
- `POST /viabilidade`:
|
||||||
|
- Quando uma requisição POST é feita para `/api/viabilidade`, o Express direciona a chamada para a função `handleViabilidade` no `contratacaoController`.
|
||||||
|
- Esta rota é usada para verificar a viabilidade de um serviço em um determinado endereço.
|
||||||
|
|
||||||
|
- `POST /prospecto`:
|
||||||
|
- Quando uma requisição POST é feita para `/api/prospecto`, a chamada é direcionada para a função `handleCriarProspecto` no `contratacaoController`.
|
||||||
|
- Esta rota é usada para criar um novo cliente potencial (prospecto) no sistema.
|
||||||
|
|
||||||
|
4. Finalmente, o objeto `router` configurado é exportado para ser usado pelo `app.js`.
|
||||||
|
|
||||||
|
Este arquivo centraliza a definição de todas as rotas da API, mantendo o código organizado e facilitando a visualização de todos os endpoints disponíveis.
|
||||||
|
*/
|
||||||
@ -1,40 +0,0 @@
|
|||||||
const apiConfig = require("../config/apiConfig.js")
|
|
||||||
const axios = require("axios");
|
|
||||||
|
|
||||||
|
|
||||||
// Geocodifica um endereço usando a API do Google Maps
|
|
||||||
|
|
||||||
async function geocodeWithGoogle(address) {
|
|
||||||
const key = apiConfig.googleApiKey;
|
|
||||||
if (!key) return null;
|
|
||||||
try {
|
|
||||||
const url = 'https://maps.googleapis.com/maps/api/geocode/json';
|
|
||||||
const r = await axios.get(url, {
|
|
||||||
params: { address, key },
|
|
||||||
timeout: 10000,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Valida a resposta e extrai as coordenadas
|
|
||||||
if (!r || r.status !== 200) {
|
|
||||||
console.warn(`geocodeWithGoogle unexpected status for '${address}': ${r && r.status}`);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verifica se há resultados válidos
|
|
||||||
|
|
||||||
if (r.data && Array.isArray(r.data.results) && r.data.results.length > 0) {
|
|
||||||
const loc = r.data.results[0].geometry && r.data.results[0].geometry.location;
|
|
||||||
const lat = loc && (loc.lat !== undefined ? Number(loc.lat) : NaN);
|
|
||||||
const lng = loc && (loc.lng !== undefined ? Number(loc.lng) : NaN);
|
|
||||||
if (!Number.isNaN(lat) && !Number.isNaN(lng)) {
|
|
||||||
return { lat, lon: lng };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
} catch (e) {
|
|
||||||
console.warn(`geocodeWithGoogle error for '${address}': ${e && e.message}`, e && e.stack);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { geocodeWithGoogle };
|
|
||||||
@ -32,4 +32,22 @@ const getConsultaCep = async (rawCep, rawNumero) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = { getConsultaCep };
|
module.exports = { getConsultaCep };
|
||||||
|
|
||||||
|
/*
|
||||||
|
DESCRIÇÃO:
|
||||||
|
Este arquivo define um serviço para consultar endereços a partir de um CEP.
|
||||||
|
|
||||||
|
FLUXO:
|
||||||
|
1. É chamado principalmente pelo `contratacao.service.js`.
|
||||||
|
2. Recebe um CEP e um número.
|
||||||
|
3. Formata e valida o CEP.
|
||||||
|
4. Realiza uma requisição POST para a API externa `https://api.cep.rest/`.
|
||||||
|
5. Trata a resposta da API:
|
||||||
|
- Se o CEP não for encontrado (código 404), retorna `null`.
|
||||||
|
- Se houver outro erro na API, lança uma exceção.
|
||||||
|
- Se for bem-sucedido, anexa o número ao objeto de dados e retorna os dados do endereço.
|
||||||
|
6. Em caso de erro na comunicação, loga o erro e lança uma exceção genérica.
|
||||||
|
|
||||||
|
Este serviço abstrai a complexidade da comunicação com a API de CEP, fornecendo uma interface simples para outras partes da aplicação obterem dados de endereço.
|
||||||
|
*/
|
||||||
@ -47,3 +47,27 @@ const consultaViabilidade = async (lat, lon) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.exports = { consultaViabilidade };
|
module.exports = { consultaViabilidade };
|
||||||
|
|
||||||
|
/*
|
||||||
|
DESCRIÇÃO:
|
||||||
|
Este arquivo define um serviço para consultar a API "GeoGrid", que parece ser um sistema de geolocalização para verificar a viabilidade de serviço em um determinado local.
|
||||||
|
|
||||||
|
FLUXO:
|
||||||
|
1. É chamado pelo `contratacao.service.js`, recebendo coordenadas de latitude e longitude.
|
||||||
|
2. Busca as credenciais da API (URL, chave e cookie) a partir do `apiConfig`.
|
||||||
|
3. Monta um objeto de parâmetros para a requisição GET, incluindo:
|
||||||
|
- `raio`: um raio de busca de 5000 metros.
|
||||||
|
- `latitude` e `longitude`: as coordenadas do ponto de consulta.
|
||||||
|
- `itens[]`: especifica o que procurar (neste caso, "caixa").
|
||||||
|
- Parâmetros de ordenação e consulta.
|
||||||
|
4. Utiliza a biblioteca `qs` para serializar os parâmetros corretamente, especialmente o array `itens[]`.
|
||||||
|
5. Loga no console um comando `curl` equivalente, o que é uma excelente prática para depuração, permitindo replicar a requisição fora da aplicação.
|
||||||
|
6. Executa a requisição GET para a URL do GeoGrid usando `axios`, passando os parâmetros e os cabeçalhos de autenticação (`api-key` and `Cookie`).
|
||||||
|
7. Processa a resposta:
|
||||||
|
- Extrai o array `registros` da resposta.
|
||||||
|
- Pega apenas o primeiro item desse array.
|
||||||
|
- Retorna o primeiro registro encontrado, encapsulado em um objeto `{ data: primeiro }` para manter consistência com o que o `contratacao.service` espera (`viabilidade.data`).
|
||||||
|
8. Em caso de erro na requisição, loga a mensagem de erro e lança uma exceção.
|
||||||
|
|
||||||
|
Este serviço abstrai a interação com a API GeoGrid, expondo uma função simples (`consultaViabilidade`) para o resto da aplicação.
|
||||||
|
*/
|
||||||
61
src/shared/apis/googleService.js
Normal file
61
src/shared/apis/googleService.js
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
const apiConfig = require("../config/apiConfig.js")
|
||||||
|
const axios = require("axios");
|
||||||
|
|
||||||
|
|
||||||
|
// Geocodifica um endereço usando a API do Google Maps
|
||||||
|
|
||||||
|
async function geocodeWithGoogle(address) {
|
||||||
|
const key = apiConfig.googleApiKey;
|
||||||
|
if (!key) return null;
|
||||||
|
try {
|
||||||
|
const url = 'https://maps.googleapis.com/maps/api/geocode/json';
|
||||||
|
const r = await axios.get(url, {
|
||||||
|
params: { address, key },
|
||||||
|
timeout: 10000,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Valida a resposta e extrai as coordenadas
|
||||||
|
if (!r || r.status !== 200) {
|
||||||
|
console.warn(`geocodeWithGoogle unexpected status for '${address}': ${r && r.status}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifica se há resultados válidos
|
||||||
|
|
||||||
|
if (r.data && Array.isArray(r.data.results) && r.data.results.length > 0) {
|
||||||
|
const loc = r.data.results[0].geometry && r.data.results[0].geometry.location;
|
||||||
|
const lat = loc && (loc.lat !== undefined ? Number(loc.lat) : NaN);
|
||||||
|
const lng = loc && (loc.lng !== undefined ? Number(loc.lng) : NaN);
|
||||||
|
if (!Number.isNaN(lat) && !Number.isNaN(lng)) {
|
||||||
|
return { lat, lon: lng };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(`geocodeWithGoogle error for '${address}': ${e && e.message}`, e && e.stack);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { geocodeWithGoogle };
|
||||||
|
|
||||||
|
/*
|
||||||
|
DESCRIÇÃO:
|
||||||
|
Este arquivo define um serviço para interagir com a API de Geocodificação do Google Maps. Sua função é converter um endereço em formato de texto (string) para um par de coordenadas geográficas (latitude e longitude).
|
||||||
|
|
||||||
|
FLUXO:
|
||||||
|
1. É chamado pelo `contratacao.service.js`, recebendo uma string de endereço.
|
||||||
|
2. Obtém a chave da API do Google a partir do `apiConfig`. Se a chave não estiver configurada, a função retorna `null` imediatamente para evitar erros.
|
||||||
|
3. Define a URL da API de Geocodificação do Google.
|
||||||
|
4. Executa uma requisição GET usando `axios`, passando o endereço e a chave da API como parâmetros. Define um `timeout` de 10 segundos para evitar que a aplicação fique presa em requisições demoradas.
|
||||||
|
5. Realiza uma validação rigorosa da resposta:
|
||||||
|
- Verifica se a resposta foi recebida e se o status HTTP é 200.
|
||||||
|
- Verifica se o corpo da resposta (`r.data`) contém um array de `results` com pelo menos um item.
|
||||||
|
- Acessa a geometria do primeiro resultado para obter o objeto `location`.
|
||||||
|
- Extrai `lat` e `lng` do objeto de localização, convertendo-os para números.
|
||||||
|
- Se `lat` e `lng` forem números válidos, retorna um objeto no formato `{ lat, lon: lng }`. O `lon` é renomeado para se alinhar com o que o `geogridService` espera.
|
||||||
|
6. Se qualquer uma das validações falhar, a função retorna `null`, indicando que a geocodificação não foi bem-sucedida.
|
||||||
|
7. Em caso de erro na requisição (ex: timeout, erro de rede), o erro é capturado, uma mensagem de aviso é logada no console, e a função retorna `null`.
|
||||||
|
|
||||||
|
Este serviço é um componente crucial para a verificação de viabilidade, pois traduz um endereço textual em coordenadas precisas que podem ser usadas por outros serviços de geolocalização como o GeoGrid.
|
||||||
|
*/
|
||||||
@ -65,3 +65,30 @@ const criarProspectHubsoft = async (prospectData) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { criarProspectHubsoft };
|
module.exports = { criarProspectHubsoft };
|
||||||
|
|
||||||
|
/*
|
||||||
|
DESCRIÇÃO:
|
||||||
|
Este arquivo contém os serviços para interagir com a API do Hubsoft, um sistema de gestão. As funções aqui são responsáveis pela autenticação e pela criação de "prospectos" (clientes potenciais).
|
||||||
|
|
||||||
|
FUNÇÕES:
|
||||||
|
- hubsoftToken():
|
||||||
|
1. É uma função interna, não exportada, usada para obter um token de autenticação OAuth 2.0.
|
||||||
|
2. Busca as credenciais do Hubsoft (client_id, client_secret, username, password, etc.) a partir do `apiConfig`.
|
||||||
|
3. Monta o corpo da requisição de autenticação.
|
||||||
|
4. Usa a biblioteca `qs` para serializar o corpo no formato `application/x-www-form-urlencoded`, que é o padrão para fluxos OAuth.
|
||||||
|
5. Realiza uma requisição POST para a URL de autenticação do Hubsoft.
|
||||||
|
6. Se a autenticação for bem-sucedida, extrai e retorna o `access_token` da resposta.
|
||||||
|
7. Em caso de erro, loga a resposta de erro do Hubsoft (se disponível) e lança uma exceção.
|
||||||
|
|
||||||
|
- criarProspectHubsoft(prospectData):
|
||||||
|
1. É a função principal exportada, chamada pelo `contratacao.service.js`.
|
||||||
|
2. Primeiro, chama a função `hubsoftToken()` para obter um token de acesso válido.
|
||||||
|
3. Monta o `payload` (corpo da requisição) para a criação do prospecto, mapeando os dados recebidos (`prospectData`) para o formato esperado pela API do Hubsoft.
|
||||||
|
4. Realiza uma requisição POST para o endpoint de criação de prospecto do Hubsoft (`/api/v1/integracao/prospecto`).
|
||||||
|
5. Inclui o token de acesso no cabeçalho `Authorization` como um "Bearer token".
|
||||||
|
6. Define o `Content-Type` como `application/json` para enviar o payload.
|
||||||
|
7. Se a criação for bem-sucedida, loga a resposta e a retorna para o serviço.
|
||||||
|
8. Em caso de erro (ex: token inválido, dados do prospecto incorretos), loga o erro e lança uma exceção.
|
||||||
|
|
||||||
|
Este serviço encapsula toda a complexidade da comunicação com a API do Hubsoft, desde a autenticação até a criação de registros.
|
||||||
|
*/
|
||||||
52
src/shared/config/apiConfig.js
Normal file
52
src/shared/config/apiConfig.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
const dotenv = require("dotenv");
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
// Google API Key
|
||||||
|
const googleApiKey = process.env.GOOGLE_API_KEY;
|
||||||
|
|
||||||
|
// Geogrid API Configs
|
||||||
|
const geogridApiUrl = process.env.GEOGRID_API_URL;
|
||||||
|
const geogridApiKey = process.env.GEOGRID_API_KEY;
|
||||||
|
const geogridApiCookie = process.env.GEOGRID_API_COOKIE;
|
||||||
|
|
||||||
|
// Hubsoft API Configs
|
||||||
|
const hubsoftUrl = process.env.HUBSOFT_URL;
|
||||||
|
const hubsoftAuthUrl = `${process.env.HUBSOFT_URL}oauth/token`;
|
||||||
|
const hubsoftClientId = process.env.HUBSOFT_CLIENT_ID;
|
||||||
|
const hubsoftClientSecret = process.env.HUBSOFT_CLIENT_SECRET;
|
||||||
|
const hubsoftUsername = process.env.HUBSOFT_USERNAME;
|
||||||
|
const hubsoftPassword = process.env.HUBSOFT_PASSWORD;
|
||||||
|
const hubsoftGrantType = process.env.HUBSOFT_GRANT_TYPE;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
googleApiKey: googleApiKey,
|
||||||
|
geogridApiUrl: geogridApiUrl,
|
||||||
|
geogridApiKey: geogridApiKey,
|
||||||
|
geogridApiCookie: geogridApiCookie,
|
||||||
|
hubsoftUrl: hubsoftUrl,
|
||||||
|
|
||||||
|
hubsoftAuthUrl: hubsoftAuthUrl,
|
||||||
|
hubsoftClientId: hubsoftClientId,
|
||||||
|
hubsoftClientSecret: hubsoftClientSecret,
|
||||||
|
hubsoftUsername: hubsoftUsername,
|
||||||
|
hubsoftPassword: hubsoftPassword,
|
||||||
|
hubsoftGrantType: hubsoftGrantType
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
DESCRIÇÃO:
|
||||||
|
Este arquivo é o ponto central de configuração para todas as APIs externas utilizadas pela aplicação. Ele é responsável por carregar as variáveis de ambiente (a partir de um arquivo `.env`) e exportá-las em um único objeto para serem consumidas por outros módulos, principalmente os serviços em `src/shared/apis/`.
|
||||||
|
|
||||||
|
FLUXO:
|
||||||
|
1. Utiliza o pacote `dotenv` para carregar as variáveis definidas em um arquivo `.env` no diretório raiz do projeto para dentro do `process.env` do Node.js.
|
||||||
|
2. Lê as variáveis de ambiente específicas para cada API:
|
||||||
|
- `GOOGLE_API_KEY` para a API do Google.
|
||||||
|
- `GEOGRID_API_URL`, `GEOGRID_API_KEY`, `GEOGRID_API_COOKIE` para a API do GeoGrid.
|
||||||
|
- `HUBSOFT_URL`, `HUBSOFT_CLIENT_ID`, `HUBSOFT_CLIENT_SECRET`, etc., para a API do Hubsoft.
|
||||||
|
3. A URL de autenticação do Hubsoft (`hubsoftAuthUrl`) é construída dinamicamente a partir da URL base.
|
||||||
|
4. Exporta um objeto contendo todas essas variáveis, fornecendo um acesso limpo e centralizado para outras partes do código.
|
||||||
|
|
||||||
|
OBJETIVO:
|
||||||
|
- **Centralização:** Manter todas as chaves de API e URLs em um só lugar, facilitando a manutenção.
|
||||||
|
- **Segurança:** Abstrair o acesso direto ao `process.env` e evitar que segredos (como API keys) sejam espalhados por todo o código. Ao usar variáveis de ambiente, o código pode ser compartilhado em repositórios de forma segura, sem expor as credenciais, que permanecem apenas no arquivo local `.env` (que não deve ser versionado).
|
||||||
|
*/
|
||||||
36
src/shared/config/environment.js
Normal file
36
src/shared/config/environment.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const dotenv = require('dotenv');
|
||||||
|
|
||||||
|
function loadEnv() {
|
||||||
|
// Define 'development' como padrão se NODE_ENV não estiver setado
|
||||||
|
const nodeEnv = process.env.NODE_ENV || 'development';
|
||||||
|
const envFile = `.env.${nodeEnv}`;
|
||||||
|
const envPath = path.resolve(process.cwd(), envFile);
|
||||||
|
|
||||||
|
const result = dotenv.config({ path: envPath });
|
||||||
|
|
||||||
|
if (result.error) {
|
||||||
|
console.warn(`Atenção: Não foi possível carregar o arquivo ${envFile}. Certifique-se de que ele existe.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = loadEnv;
|
||||||
|
|
||||||
|
/*
|
||||||
|
DESCRIÇÃO:
|
||||||
|
Este arquivo é responsável por carregar variáveis de ambiente de arquivos `.env` específicos para cada ambiente de execução (development, production, test, etc.). Isso permite que a aplicação tenha configurações diferentes dependendo de onde está rodando.
|
||||||
|
|
||||||
|
FLUXO:
|
||||||
|
1. Exporta uma única função, `loadEnv`.
|
||||||
|
2. Esta função é chamada no início do ciclo de vida da aplicação, dentro do `app.js`.
|
||||||
|
3. A função `loadEnv` verifica a variável de ambiente `process.env.NODE_ENV`. Se não estiver definida, assume `'development'` como padrão.
|
||||||
|
4. Com base no ambiente (`nodeEnv`), ele constrói o nome do arquivo de configuração esperado (ex: `.env.development`).
|
||||||
|
5. Usa o `path.resolve` para criar o caminho absoluto para esse arquivo, garantindo que ele seja encontrado corretamente a partir do diretório raiz do projeto.
|
||||||
|
6. Chama `dotenv.config({ path: envPath })` para carregar as variáveis do arquivo `.env` específico para o `process.env`.
|
||||||
|
7. Se o arquivo `.env` específico do ambiente não for encontrado, `dotenv.config` retorna um erro. O código captura isso e exibe um aviso (`console.warn`) em vez de quebrar a aplicação, o que é uma abordagem robusta.
|
||||||
|
|
||||||
|
OBJETIVO:
|
||||||
|
- Permitir configurações diferentes para desenvolvimento e produção (e outros ambientes). Por exemplo, a URL do banco de dados ou as chaves de API podem ser diferentes.
|
||||||
|
- Manter a configuração do ambiente separada da lógica principal, tornando o código mais limpo e portável.
|
||||||
|
- Centralizar a lógica de carregamento de ambiente em um único local.
|
||||||
|
*/
|
||||||
88
src/shared/utils/logger.js
Normal file
88
src/shared/utils/logger.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
const winston = require('winston');
|
||||||
|
const path = require('path');
|
||||||
|
require('winston-daily-rotate-file');
|
||||||
|
|
||||||
|
// O diretório de logs é criado pelo script de inicialização, mas garantimos aqui também.
|
||||||
|
const logsDir = path.resolve(process.cwd(), 'logs');
|
||||||
|
|
||||||
|
// Configuração do logger com winston
|
||||||
|
const logger = winston.createLogger({
|
||||||
|
level: 'info',
|
||||||
|
format: winston.format.combine(
|
||||||
|
winston.format.timestamp({
|
||||||
|
format: 'YYYY-MM-DD HH:mm:ss'
|
||||||
|
}),
|
||||||
|
winston.format.errors({ stack: true }), // Mostra stack trace de erros
|
||||||
|
winston.format.json()
|
||||||
|
),
|
||||||
|
transports: [
|
||||||
|
// Log geral da aplicação
|
||||||
|
new winston.transports.DailyRotateFile({
|
||||||
|
filename: path.join(logsDir, 'app-%DATE%.log'),
|
||||||
|
datePattern: 'YYYY-MM-DD',
|
||||||
|
zippedArchive: true,
|
||||||
|
maxSize: '5m',
|
||||||
|
maxFiles: '10d',
|
||||||
|
}),
|
||||||
|
// Log de erros
|
||||||
|
new winston.transports.DailyRotateFile({
|
||||||
|
filename: path.join(logsDir, 'error-%DATE%.log'),
|
||||||
|
level: 'error',
|
||||||
|
datePattern: 'YYYY-MM-DD',
|
||||||
|
zippedArchive: true,
|
||||||
|
maxSize: '5m',
|
||||||
|
maxFiles: '10d',
|
||||||
|
})
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Log no console em desenvolvimento
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
logger.add(new winston.transports.Console({
|
||||||
|
format: winston.format.combine(
|
||||||
|
winston.format.colorize(),
|
||||||
|
winston.format.printf((info) => {
|
||||||
|
const { timestamp, level, message, stack, ...meta } = info;
|
||||||
|
let logMessage = `${timestamp} [${level}]: ${stack || message}`;
|
||||||
|
if (Object.keys(meta).length) {
|
||||||
|
logMessage += ` ${JSON.stringify(meta, null, 2)}`;
|
||||||
|
}
|
||||||
|
return logMessage;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = logger;
|
||||||
|
|
||||||
|
/*
|
||||||
|
DESCRIÇÃO:
|
||||||
|
Este arquivo configura e exporta uma instância de logger centralizada para toda a aplicação, utilizando a biblioteca `winston`. O objetivo é ter um sistema de logging robusto, que armazena logs em arquivos e se comporta de maneira diferente em ambientes de desenvolvimento e produção.
|
||||||
|
|
||||||
|
FLUXO E CONFIGURAÇÃO:
|
||||||
|
1. Importa as bibliotecas `winston` e `winston-daily-rotate-file`. A segunda é uma extensão para rotacionar arquivos de log automaticamente (por data, tamanho, etc.).
|
||||||
|
2. Define o diretório de logs (`logs/`) na raiz do projeto.
|
||||||
|
3. Cria a instância do logger com `winston.createLogger()`:
|
||||||
|
- `level: 'info'`: Define o nível mínimo de log a ser registrado. Logs com severidade menor (como `debug` ou `verbose`) serão ignorados.
|
||||||
|
- `format`: Define o formato das mensagens de log.
|
||||||
|
- `timestamp`: Adiciona um timestamp a cada log.
|
||||||
|
- `errors({ stack: true })`: Garante que, ao logar um objeto de erro, sua stack trace seja incluída.
|
||||||
|
- `json()`: Formata a saída do log como JSON, o que é ideal para parseamento por sistemas de monitoramento.
|
||||||
|
4. Configura os "Transports" (saídas de log):
|
||||||
|
- **DailyRotateFile (app)**:
|
||||||
|
- Salva todos os logs de nível `info` e acima em arquivos diários (ex: `app-2023-10-27.log`).
|
||||||
|
- `zippedArchive: true`: Compacta os arquivos de log antigos.
|
||||||
|
- `maxSize: '5m'`: Rotaciona o arquivo se ele atingir 5MB.
|
||||||
|
- `maxFiles: '10d'`: Mantém os logs dos últimos 10 dias.
|
||||||
|
- **DailyRotateFile (error)**:
|
||||||
|
- Salva apenas logs de nível `error` em arquivos separados (ex: `error-2023-10-27.log`), facilitando a análise de falhas.
|
||||||
|
5. **Log de Console (Apenas em Desenvolvimento)**:
|
||||||
|
- Se a variável `NODE_ENV` não for `'production'`, um transport adicional é adicionado para exibir logs no console.
|
||||||
|
- O formato para o console é mais amigável para leitura humana, usando `colorize()` para cores e `printf` para um formato de string personalizado que exibe a stack trace de erros de forma legível.
|
||||||
|
|
||||||
|
UTILIZAÇÃO:
|
||||||
|
- Em qualquer outro arquivo, o logger pode ser importado e usado assim:
|
||||||
|
`const logger = require('./shared/utils/logger');`
|
||||||
|
`logger.info('Mensagem informativa');`
|
||||||
|
`logger.error('Ocorreu um erro', new Error('detalhes'));`
|
||||||
|
*/
|
||||||
Loading…
Reference in New Issue
Block a user