feat: send email to locked users explaining lock reason and support contact #26978
+544
−37
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.
What does this PR do?
When a user is auto-locked (or has their
lockedfield set totrue), this PR dispatches a job via tasker to send the user an email explaining:Implements both async (via trigger.dev) and sync variants for sending the locked user email, using the same DI (Dependency Injection) pattern as
MonthlyProrationTasker.Changes
sendUserLockedEmaillockUserfunction to automatically dispatch the email task when a user is lockedsendUserLockedEmailAsyncandsendUserLockedEmailSyncexported functions for flexibilitylockUserto fetch user'snameandlocalefor personalized emailsUpdates since last revision
MonthlyProrationTasker:IUserLockedEmailTaskerinterface withsendEmailmethodUserLockedEmailTaskerextendingTaskerbase class (provides automatic async→sync fallback)UserLockedEmailSyncTaskerfor synchronous email sendingUserLockedEmailTriggerDevTaskerfor async execution via trigger.devpackages/features/ee/api-keys/di/tasker/getUserLockedEmailTasker)ENABLE_ASYNC_TASKERto constants mocks:@calcom/lib/__mocks__/constants.ts(global mock)apps/web/test/lib/getSchedule/futureLimit.timezone.test.ts(test-specific mock)Mandatory Tasks (DO NOT REMOVE)
How should this be tested?
Trigger a user lock by either:
lockUser("userId", "123", LockReason.RATE_LIMIT)Verify the DI-based tasker dispatches the email task
When the task is processed, verify the email is sent with:
For sync variant testing:
Checklist
Human Review Checklist
sendUserLockedEmailAsynclogs errors but doesn't throw - confirm this is desired behaviortasks/sendUserLockedEmail.ts) and new DI-based implementationLink to Devin run: https://app.devin.ai/sessions/fc8c8aeabef641b7bbf8e331f5750588
Requested by: @sean-brydon