Add /api/tips/stats endpoint with topic statistics#7
Add /api/tips/stats endpoint with topic statistics#7RohitChavan16 wants to merge 1 commit intotimothywarner-org:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a new statistics endpoint to the tips API that aggregates tip counts by topic. The implementation reads metadata from the tips data file to ensure all topics are represented in the response, even if they have zero tips.
Key Changes
- Added
getStatsservice function to compute tip statistics by topic - Created
readTipsFilehelper to access full file structure including metadata - Exposed statistics through new
GET /api/tips/statscontroller and route
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/services/tipService.js | Implements stats aggregation logic and new file reader helper |
| src/routes/tips.js | Registers /stats endpoint in router configuration |
| src/controllers/tipController.js | Adds controller handler for stats requests |
| router.get('/random', tipController.getRandom); | ||
| router.get('/stats', tipController.getStats); |
There was a problem hiding this comment.
The /stats route is placed after /random but before /topic/:topic. This ordering is correct and prevents /stats from being matched by the /:id route, but the route should be moved before /random to maintain consistency with the pattern of placing static routes before parameterized ones.
| router.get('/random', tipController.getRandom); | |
| router.get('/stats', tipController.getStats); | |
| router.get('/stats', tipController.getStats); | |
| router.get('/random', tipController.getRandom); |
| const topic = tip.topic?.toLowerCase(); | ||
| if (topic && byTopic.hasOwnProperty(topic)) { |
There was a problem hiding this comment.
The case-insensitive comparison converts tip.topic to lowercase (line 144), but the metadata topics array is not lowercased when initializing byTopic (lines 139-141). This creates a mismatch where tips won't be counted if metadata.topics contains mixed-case values. Either lowercase the metadata topics during initialization or change the counting logic to use the original case.
| const topic = tip.topic?.toLowerCase(); | |
| if (topic && byTopic.hasOwnProperty(topic)) { | |
| const topic = tip.topic; | |
| if (topic && Object.prototype.hasOwnProperty.call(byTopic, topic)) { |
| } | ||
| }; | ||
|
|
||
|
|
There was a problem hiding this comment.
Extra blank line at line 92. Remove one blank line to maintain consistent spacing between functions.
| } | ||
| } | ||
|
|
||
| async function readTipsFile() { |
There was a problem hiding this comment.
Missing JSDoc comment for the readTipsFile function. All public and exported functions should have JSDoc documentation describing their purpose, return value, and any parameters.
Description
This PR adds a new
GET /api/tips/statsendpoint that returns tip statistics grouped by topic.Fixes #5
Changes
Why
This enables dashboard-friendly analytics without duplicating logic on the client.