Purav taking over PR 2216 Core Team additional hours carryover when blue squares exceed five - #2320
Open
pixelpix13 wants to merge 3 commits into
Open
Conversation
Port and complete PR #2216: include penalty hours in weekly threshold, missed-hour roll-forward, email/resend math, and integration tests for Tatyana scenarios including Bear email negative penalty bug.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Description
Core Team members who exceed five blue squares in a rolling year must carry forward missed volunteer hours plus a +1 hour penalty for each blue square beyond the fifth. Prior work (#1612, #2216) left incorrect penalty math, double-counting in infringement descriptions/emails, a broken MongoDB
$lookupinapplyMissedHourForCoreTeam, and the production Bear email bug (negative penalty hours on early blue squares). This PR ports and completes that behavior on top of the refactoreduserHelper.js, extracts aggregation intocoreTeamMissedHoursAggregation.jsfor test coverage, and adds unit + integration tests including Tatyana's priority scenarios.Supersedes HGNRest #2216 (taken over on branch
Purav-core-team-members-additional-hours-carryover). Builds on HGNRest #1612.Fixes #1141
Fixes #1281
Related PRS (if any):
missedHoursto leaderboard (merged ondevelopment)development)How reviewers test this PR (backend + UI):
Purav-core-team-members-additional-hours-carryover(this PR)developmentonly — do not checkout the #2600 branch; UI changes are already mergedThis is a backend-only PR. No new frontend PR is required.
Main changes explained:
userHelper.js→processUserForBlueSquare: ComputescoreTeamExtraHour = max(0, year-filtered BS count + 1 − 5)before the time-not-met threshold. Required hours when assigning a new cron BS =weeklycommittedHours + missedHours + coreTeamExtraHour(Core Team only).userHelper.js→buildInfringementDescription: Uses prior-weekmissedHoursandcoreTeamExtraHourseparately so penalty is not double-counted into the carryover line.userHelper.js→getInfringementEmailBody: Fixes the Bear bug (no more-3 hour(s)penalty text); shows correct owed-hours breakdown (commitment + carryover + penalty = total required); hides penalty line when penalty is 0.userHelper.js→applyMissedHourForCoreTeam: Fixed$lookuppipeline syntax; year-filtered infringement count; incremental penalty (max(0,count−5) − max(0,count−6));$setin bulkWrite; skips empty bulk ops.coreTeamMissedHoursAggregation.js(new): MongoDB aggregation pipeline for Core TeammissedHourscalculation (extracted from inline logic for unit test coverage).userHelper.js→resendBlueSquareEmailsOnlyForLastWeek: Resend path includescoreTeamExtraHourand passes baseweeklycommittedHourscorrectly for Core Team resend emails.coreTeamCarryoverHelper.test.js,coreTeamMissedHoursAggregation.test.js,getInfringementEmailBody.test.js(29 unit tests — run in CI);timeNotMetCoreTeamTest.test.js— 12 integration tests (skipped in CI, run locally with MongoMemoryServer).Penalty & carryover rules (reviewer reference)
missedHoursafter cronmax(0, commitment + prior missedHours − hours logged)Formula when cron assigns a new blue square:
required = weeklycommittedHours + missedHours + max(0, yearFilteredCount + 1 − 5)Leaderboard / profile UI (frontend
development): displays effective required asweeklycommittedHours + missedHours. Penalty hours are rolled intomissedHoursby the Sunday cron — the frontend does not calculate penalty client-side.How to test:
A. Automated tests (required — no local stack needed)
Purav-core-team-members-additional-hours-carryoveron HGNRest.npm installif needed. Use Node 20.x (nvm use 20).npm test -- src/helpers/__tests__/coreTeamCarryoverHelper.test.js src/helpers/__tests__/coreTeamMissedHoursAggregation.test.js src/helpers/__tests__/getInfringementEmailBody.test.jsnpm run test:verbose -- src/helpers/__tests__/getInfringementEmailBody.test.js -t "Bear"-3 hour/-3 hoursin output; owed total shown correctly.CIorGITHUB_ACTIONSis set):npm test -- src/test/timeNotMetCoreTeamTest.test.jsB. Local full-stack setup (optional manual verification)
.env(MongoDB, SMTP, JWT, etc.). Start Redis (redis-server; fixECONNREFUSED 127.0.0.1:6379if backend fails).npm run buildthennpm start.development. PointREACT_APP_APIENDPOINTto local API if not using staging (e.g.http://localhost:4500/api).npm install→npm run start:local→ http://localhost:5173C. Create a Core Team test user
123Welcome!.http://localhost:5173/userprofile/{userId}→ Volunteering Time tab.D. Tatyana scenarios (mirror integration tests)
Use last completed week time entries (Sunday–Saturday PST). Log tangible time dated in that window via the UI, then trigger cron helpers locally or wait for Sunday cron.
Scenario 1 — 1st BS, no penalty:
missedHours = 0, commitment 5h.assignBlueSquareForTimeNotMet→applyMissedHourForCoreTeam): expect 1 BS,missedHours = 2(5 − 3).Scenario 2 — 6th BS, +1 penalty:
missedHours = 0.missedHours = 3(2h shortfall + 1h penalty).Scenario 3 — 7th BS, +2 penalty:
missedHours = 3, commitment 5h.missedHours = 7(5h shortfall + 2h penalty).Scenario 4 — Meets hours including penalty (no new BS):
missedHours = 0.E. Manual admin blue square vs cron (critical — read before testing)
Manually adding blue squares (User Profile → Blue Squares → add, requires admin permission):
npm startmissedHoursupdatedapplyMissedHourForCoreTeamAt exactly 5 manual blue squares:
weeklycommittedHours + missedHoursonly (e.g. 10 + 0 = 10).Adding a 6th blue square manually:
missedHoursand leaderboard still unchanged until Sunday cron runs.F. UI verification (frontend
development)missedHourscarryover (from ambika fix core team unique additions in leaderboard #1083 + #2600).missedHoursafter cron runs. To demo UI without waiting for cron, an admin may temporarily setmissedHourson the profile and confirm the leaderboard tooltip updates.missedHoursstays 0 (non–Core Team path).developmentfrontend.G. Edge cases
missedHours = 0.H. Email delivery on local dev (read this if you added blue squares and got no email)
This is expected behavior, not a PR failure.
When running the backend locally (
npm start),emailSender.jsdoes not send emails unlessNODE_ENV=production(password-reset emails are the only exception):So if you manually add 5 or 6 blue squares on a local stack:
missedHourswill not update (manual add never does — see Section E)How reviewers verify email fixes without an inbox:
-3 hours)getInfringementEmailBody.test.js -t "Bear"coreTeamCarryoverHelper.test.jscoreTeamCarryoverHelper.test.js—assignBlueSquareForTimeNotMetmock assertionsThe profile subscribed / unsubscribed toggle does not block infringement emails — local
NODE_ENVis what prevents delivery.###Screenshots


Note:
HighestGoodNetworkAppdevelopment; checkoutdevelopment, not PR #2600's branch.NODE_ENV !== 'production'. Reviewers must use Section A tests for email proof — not their inbox.userProfileJobs.js, 12:00 AM PST): runsassignBlueSquareForTimeNotMetthenapplyMissedHourForCoreTeam. Manual BS added mid-week do not updatemissedHoursuntil that job runs.timeNotMetCoreTeamTest.test.jsis skipped in CI (CI/GITHUB_ACTIONS). Reviewers who cannot run MongoMemoryServer locally should rely on unit tests (29/29) + UI spot-check.