feat: implement analytics endpoints (task 28)

- Created analytics service with summary, trends, comparison, and aggregated data methods
- Implemented 5 analytics endpoints: summary, trends, comparison, aggregated, and CSV export
- Added time series data with day/week/month interval support
- Implemented period-over-period comparison metrics with percentage changes
- Added CSV export functionality using json2csv
- Updated frontend analytics service to unwrap API responses
- Fixed chart components to work with new data structure (reportCount, eventCount, litterCollected)
- Updated TypeScript types to match backend API structure
- All endpoints tested and verified working

Requirements satisfied: 5.1, 5.2, 5.3, 5.4, 5.5
This commit is contained in:
2025-11-17 00:13:07 +00:00
parent ea08bf4289
commit d91a13da60
16 changed files with 1051 additions and 78 deletions

View File

@@ -18,6 +18,7 @@
"express": "^4.21.1",
"express-validator": "^7.2.0",
"helmet": "^8.0.0",
"json2csv": "^6.0.0-alpha.2",
"multer": "^1.4.5-lts.1",
"node-cron": "^4.2.1",
"redis": "^5.9.0",
@@ -26,6 +27,7 @@
"devDependencies": {
"@types/cors": "^2.8.17",
"@types/express": "^5.0.0",
"@types/json2csv": "^5.0.7",
"@types/multer": "^1.4.12",
"@types/node": "^22.9.0",
"@types/node-cron": "^3.0.11",
@@ -778,6 +780,12 @@
"@redis/client": "^5.9.0"
}
},
"node_modules/@streamparser/json": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/@streamparser/json/-/json-0.0.6.tgz",
"integrity": "sha512-vL9EVn/v+OhZ+Wcs6O4iKE9EUpwHUqHmCtNUMWjqp+6dr85+XPOSGTEsqYNq1Vn04uk9SWlOVmx9J48ggJVT2Q==",
"license": "MIT"
},
"node_modules/@types/body-parser": {
"version": "1.19.6",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
@@ -841,6 +849,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/json2csv": {
"version": "5.0.7",
"resolved": "https://registry.npmjs.org/@types/json2csv/-/json2csv-5.0.7.tgz",
"integrity": "sha512-Ma25zw9G9GEBnX8b12R4EYvnFT6dBh8L3jwsN5EUFXa+fl2dqmbLDbNWN0XuQU3rSXdsbBeCYjI9uHU2PUBxhA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/mime": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
@@ -1064,6 +1082,15 @@
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
"integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
"license": "MIT",
"engines": {
"node": ">= 6"
}
},
"node_modules/concat-stream": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
@@ -1683,12 +1710,37 @@
"node": ">=14"
}
},
"node_modules/json2csv": {
"version": "6.0.0-alpha.2",
"resolved": "https://registry.npmjs.org/json2csv/-/json2csv-6.0.0-alpha.2.tgz",
"integrity": "sha512-nJ3oP6QxN8z69IT1HmrJdfVxhU1kLTBVgMfRnNZc37YEY+jZ4nU27rBGxT4vaqM/KUCavLRhntmTuBFqZLBUcA==",
"license": "MIT",
"dependencies": {
"@streamparser/json": "^0.0.6",
"commander": "^6.2.0",
"lodash.get": "^4.4.2"
},
"bin": {
"json2csv": "bin/json2csv.js"
},
"engines": {
"node": ">= 12",
"npm": ">= 6.13.0"
}
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT"
},
"node_modules/lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
"deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.",
"license": "MIT"
},
"node_modules/lower-case": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",