## Summary
- Adds email and in-app notifications when user subscription tier changes
- Notifications triggered by admin override, user upgrade/downgrade, and grace period auto-downgrade
- Includes previous tier, new tier, and reason for change
Fixes #59
## Changes
- Extended `TemplateKey` type with `'subscription_tier_change'`
- Added migration `007_subscription_tier_change_template.sql` with responsive HTML email template
- Added `sendTierChangeNotification()` to `NotificationsService`
- Integrated notifications into `SubscriptionsService` methods (upgrade, downgrade, adminOverride)
- Integrated notifications into `grace-period.job.ts` for auto-downgrades
## Test Plan
- [ ] Verify type-check passes
- [ ] Verify lint passes
- [ ] Test email notification sent on tier upgrade
- [ ] Test email notification sent on tier downgrade
- [ ] Test email notification sent on admin override
- [ ] Test email notification sent on grace period expiration
- [ ] Test in-app notification appears in notification bell
- [ ] Mobile + desktop responsive validation
Generated with [Claude Code](https://claude.com/claude-code)
Adds email and in-app notifications when user subscription tier changes:
- Extended TemplateKey type with 'subscription_tier_change'
- Added migration for tier change email template with HTML
- Added sendTierChangeNotification() to NotificationsService
- Integrated notifications into upgradeSubscription, downgradeSubscription, adminOverrideTier
- Integrated notifications into grace-period.job.ts for auto-downgrades
Notifications include previous tier, new tier, and reason for change.
Co-Authored-By: Claude Opus 4.5 <[email protected]>
The TemplateService only supports {{variable}} substitution, not Handlebars-style
conditionals. Changed to use a single {{additionalInfo}} variable that is built
in the service code based on upgrade/downgrade status.
Co-Authored-By: Claude Opus 4.5 <[email protected]>
The original migration already inserted the template with Handlebars conditionals.
This migration updates the existing record to use simple variable substitution.
Co-Authored-By: Claude Opus 4.5 <[email protected]>
Changed INSERT to INSERT...ON CONFLICT DO UPDATE so the migration works for:
- Fresh deployments (inserts new template)
- Existing databases (updates template to fix variable substitution)
Removed unnecessary migration 008.
Co-Authored-By: Claude Opus 4.5 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Fixes #59
Changes
TemplateKeytype with'subscription_tier_change'007_subscription_tier_change_template.sqlwith responsive HTML email templatesendTierChangeNotification()toNotificationsServiceSubscriptionsServicemethods (upgrade, downgrade, adminOverride)grace-period.job.tsfor auto-downgradesTest Plan
Generated with Claude Code
The TemplateService only supports {{variable}} substitution, not Handlebars-style conditionals. Changed to use a single {{additionalInfo}} variable that is built in the service code based on upgrade/downgrade status. Co-Authored-By: Claude Opus 4.5 <[email protected]>