|
1 | | -# Description |
2 | | -Fixes issue where the "Longest Open Issues" chart was limiting results to only 7 issues when multiple projects were selected, causing some issues to be hidden. Also fixes issue numbering consistency when multiple projects are selected. |
| 1 | +# Description |
| 2 | + |
| 3 | +This PR adds a `reasons` array to infringements in the user profile, allowing for more robust and flexible categorization of issues such as "time not met," "missing summary," "missed video call," "late reporting," or "other." |
| 4 | + |
| 5 | +The controller logic ensures reasons are consistently handled as a lowercased, deduplicated array with a safe default, which both improves data quality and simplifies future analytics or display logic. |
| 6 | + |
| 7 | +**Fixes #1686, #1817** (PRIORITY HIGH) |
| 8 | + |
| 9 | +## Related PRS (if any): |
| 10 | +[PR 1686](https://github.com/OneCommunityGlobal/HGNRest/pull/1686) - Original PR by Yu Yan taking over for Ujjwal |
| 11 | +[PR 1817](https://github.com/OneCommunityGlobal/HGNRest/pull/1817) - Attempt to resolve merge conflicts |
| 12 | + |
| 13 | +## Main changes explained: |
| 14 | + |
| 15 | +Added functionality to easily parse reasons for Blue Squares using a reasons array. Added the reasons array field to store multiple categorization reasons for each infringement. |
| 16 | + |
| 17 | +- Added `reasons` field under `infringements` in `userProfile` model with predefined options (which can be modified as required) |
| 18 | + - Type: Array of Strings |
| 19 | + - Default: `['other']` |
| 20 | + - Enum values: `'time not met'`, `'missing summary'`, `'missed video call'`, `'late reporting'`, `'other'` |
| 21 | + |
| 22 | +- Updated `addInfringements` controller logic to: |
| 23 | + - Accept reasons array from request body |
| 24 | + - Normalize values to lowercase |
| 25 | + - Remove duplicates |
| 26 | + - Filter valid enum values only |
| 27 | + - Default to `['other']` if empty or invalid |
| 28 | + |
| 29 | +- Maintains backward compatibility with existing `reason` (single string) field |
| 30 | + |
| 31 | +## How to test: |
| 32 | + |
| 33 | +1. Check out the current branch: `feat/infringement-reasons-array` |
| 34 | +2. Run `npm run build` and `npm start` to run this PR locally |
| 35 | +3. Send a POST request to `api/userProfile/:userId/addInfringement` to add an infringement |
3 | 36 |
|
4 | | -Fixes #4301 (Phase 2 Bugs - Priority Medium) |
5 | | - |
6 | | -## Related PRs (if any): |
7 | | -Related to Frontend PR: #4653 |
8 | | -To test this backend PR, you need to checkout the corresponding frontend PR branch. |
9 | | - |
10 | | -## Main changes explained: |
11 | | -- **Updated `bmIssueController.js`** - `getLongestOpenIssues` function: |
12 | | - - Removed `.slice(0, 7)` limit to return all issues from selected projects instead of just top 7 |
13 | | - - Added `issueId` to response (MongoDB `_id` as string) for consistent issue identification |
14 | | - - Added `projectId` to response to enable per-project issue numbering |
15 | | - - Added `projectName` to response to distinguish issues across projects |
16 | | - - Updated query to select `_id` field along with `issueTitle` and `issueDate` |
17 | | - - Handle empty `issueTitle` arrays by returning `null` instead of `undefined` |
18 | | - |
19 | | -## How to test: |
20 | | -1. Checkout branch `vamsidhar-fix/issue-chart-all-issues-visible` |
21 | | -2. Run `npm run build` to compile the changes |
22 | | -3. Restart the backend server |
23 | | -4. Ensure the frontend is running with the corresponding frontend PR branch |
24 | | -5. Navigate to BMDashboard → Issues → Longest Open Issues chart |
25 | | -6. **Test Scenario 1: Select only "Building 3"** |
26 | | - - Should show all Building 3 issues (e.g., "Paint Peeling in Conference Room", "Issue #1", "Issue #2", "Issue #3", "Issue #4") |
27 | | - - Verify all issues are displayed, not limited to 7 |
28 | | -7. **Test Scenario 2: Select "Building 3" and "Building 1" together** |
29 | | - - Should show ALL issues from both projects (not limited to 7) |
30 | | - - Should include all Building 3 issues (Issue #1, #2, #3, #4) AND all Building 1 issues |
31 | | - - Verify no issues are missing compared to when selecting projects individually |
32 | | - - Check backend console logs - should see: `[getLongestOpenIssues] Total issues found: X, Returning: X issues` where X is the total count (should be more than 7 for multiple projects) |
33 | | -8. **Test Scenario 3: Select multiple projects with many issues** |
34 | | - - Verify all issues are displayed, sorted by duration (longest first) |
35 | | - - Check backend console logs to verify the count of issues being returned |
36 | | - - Verify the response includes `issueId`, `projectId`, and `projectName` fields for each issue |
37 | | - |
38 | | -## Expected behavior: |
39 | | -- When selecting multiple projects, ALL issues from all selected projects should be visible |
40 | | -- Issues should be sorted by duration (longest open first) |
41 | | -- No limit on the number of issues displayed |
42 | | -- Each issue should have a unique `issueId` for consistent identification |
43 | | -- Response should include `projectId` and `projectName` for frontend processing |
44 | | - |
45 | | -## Technical details: |
46 | | -- The API endpoint `/bm/issues/longest-open` now returns all matching issues instead of limiting to 7 |
47 | | -- Response includes `issueId`, `projectId`, and `projectName` fields for frontend processing |
48 | | -- Issues with empty `issueTitle` arrays return `null` for `issueName` (frontend will generate names) |
49 | | -- Debug logging added to verify issue counts in console |
50 | | - |
51 | | -## Note: |
52 | | -This PR only includes backend changes. The frontend PR (#4653) will handle: |
53 | | -- Using `issueId` for consistent issue numbering |
54 | | -- Per-project issue numbering to avoid conflicts |
55 | | -- Prefixing unnamed issues with project name when multiple projects are selected |
| 37 | +Important: |
| 38 | +- The `requestor` must be a valid user id or requestor object that resolves to a user with the `addInfringements` permission. |
| 39 | +- For local testing, use a user whose role is `Owner`, `Administrator`, `Manager`, or `Mentor`, or a user with the `addInfringements` front permission. |
| 40 | + |
| 41 | +**Example request body:** |
| 42 | +```json |
| 43 | +{ |
| 44 | + "requestor": "<your-user-id>", |
| 45 | + "blueSquare": { |
| 46 | + "date": "2025-09-03", |
| 47 | + "description": "PR Testing Add Infringement", |
| 48 | + "reasons": ["time not met", "missing summary", "missed video call", "late reporting", "other"] |
| 49 | + } |
| 50 | +} |
| 51 | +``` |
| 52 | + |
| 53 | +**Valid reasons values:** |
| 54 | +- `'time not met'` |
| 55 | +- `'missing summary'` |
| 56 | +- `'missed video call'` |
| 57 | +- `'late reporting'` |
| 58 | +- `'other'` (default) |
| 59 | + |
| 60 | +4. Verify in the database that the infringement was added with the reasons array properly stored |
| 61 | + |
| 62 | +## Screenshots or videos of changes: |
| 63 | + |
| 64 | +### API Test (Postman/Insomnia): |
| 65 | +``` |
| 66 | +POST http://localhost:4500/api/userProfile/68acd7da7787ad0055d8517b/addInfringement |
| 67 | +
|
| 68 | +Body: |
| 69 | +{ |
| 70 | + "requestor":"68acd7da7787ad0055d8517b", |
| 71 | + "blueSquare": { |
| 72 | + "date":"2025-09-03", |
| 73 | + "description":"PR Testing Add Infringement", |
| 74 | + "reasons":["time not met", "missing summary", "missed video call", "late reporting", "other"] |
| 75 | + } |
| 76 | +} |
| 77 | +
|
| 78 | +Response: 200 OK |
| 79 | +{ |
| 80 | + "_id": "68acd7da7787ad0055d8517b" |
| 81 | +} |
| 82 | +``` |
| 83 | + |
| 84 | +### Database Verification: |
| 85 | +The `infringements` array in the user profile document should now contain: |
| 86 | +```json |
| 87 | +{ |
| 88 | + "infringements": [ |
| 89 | + { |
| 90 | + "date": "2025-09-03", |
| 91 | + "description": "PR Testing Add Infringement", |
| 92 | + "reasons": [ |
| 93 | + "time not met", |
| 94 | + "missing summary", |
| 95 | + "missed video call", |
| 96 | + "late reporting", |
| 97 | + "other" |
| 98 | + ], |
| 99 | + "_id": "68b8d5b874bbf9895405cf40" |
| 100 | + } |
| 101 | + ] |
| 102 | +} |
| 103 | +``` |
| 104 | + |
| 105 | +## Notes: |
| 106 | + |
| 107 | +- This PR resolves the merge conflicts from the original PRs #1686 and #1817 |
| 108 | +- All existing fields in the user profile model are preserved |
| 109 | +- The new `reasons` array field is backward compatible - existing infringements without reasons will default to `['other']` |
0 commit comments