fix(email): Exclude skipPreferences students from prefs email chain - #61
Merged
tylermenezes merged 1 commit intoSep 18, 2026
Conversation
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.
Detail bug report: View on Detail
Bug
Students flagged with
skipPreferences: true(designated by their partner institution for manual matching) were receiving the entire "Submit Your Project Preferences" email chain —[Action Required] Submit Your Project Preferencesplus two reminders. The resolver layer hard-blocks these students from ever creating aProjectPreference(src/resolvers/Match.ts:33,67throws whenstudent.skipPreferencesis set), so the absence of preferences is expected for this population, not delinquent.Root cause: the
whereclause insrc/email/templates/studentMatchPrefs.ts,studentMatchPrefsReminder.ts, andstudentMatchPrefsReminder2.tsfiltered onprojectPreferences: { none: {} }but did not filter onskipPreferences: false, so manually-matched students were queried as if they were delinquent in submitting preferences. They were only indirectly removed from the chain once an admin/manager attached a project (viaprojects: { none: {} }), a timing-dependent compensation the template cannot rely on.Fix
Added
skipPreferences: falseto thewhereclause in all three sibling templates so manually-matched students are excluded from the entire chain, independent of operator timing:src/email/templates/studentMatchPrefs.ts:17src/email/templates/studentMatchPrefsReminder.ts:19src/email/templates/studentMatchPrefsReminder2.ts:19This is the system's intended exclusion signal — the only code that consults
skipPreferencesoutside the resolvers. No schema, dispatcher, or resolver changes required.Testing
tests/testStudentMatchPrefsSkipPreferences.ts,node:test+node:assert/strict, matching the existingtests/testSlackReporting.tsconvention). It injects an in-memory mockPrismaClientwhosestudent.findManyre-evaluates every predicate in thewhereclause against seededStudent/Event/EmailSentrows, then calls the realgetListof each of the three templates. It verifies flagged students are excluded from all three chain steps, flagged students with a prior chainEmailSentrow do not progress to the next step, normal students are still targeted, the other exclusion paths (status,projectPreferences.none,projects.none,eventId, reminder predecessor gates) still suppress email, and thewhereobject structurally containsskipPreferences: false.npx tsc --skipLibCheck --noEmit) is clean.tests/testSlackReporting.tsstill passes (no regression).@typescript-eslint/typescript@5.xparser deprecation that fires identically on unmodified files; no new violation.sendEmailsForGeneratorinsrc/email/index.ts) against a seeded trigger state. Confirmed noEmailSentrow is written for the flagged student for any of the three templateemailIds while the normal student still receives the chain, and the dedup cap is unchanged. Also ran the realemailSendautomation against a Mailpit SMTP relay and confirmed via its HTTP API that the flagged student's mailbox receives zero chain messages while the normal student's receives[Action Required] Submit Your Project Preferences. Reverting the fix causes both end-to-end runs to fail in the expected way (the flagged student receives the misdirected email and gets anEmailSentrow).Automatic Fixes PRs can be configured here.