Skip to content

Added email notifications toggle for gift subscription events#27307

Merged
mike182uk merged 2 commits intomainfrom
BER-3523-add-settings-toggle
Apr 13, 2026
Merged

Added email notifications toggle for gift subscription events#27307
mike182uk merged 2 commits intomainfrom
BER-3523-add-settings-toggle

Conversation

@mike182uk
Copy link
Copy Markdown
Member

ref https://linear.app/ghost/issue/BER-3523

Added email notifications toggle for gift subscription events

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 9, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a new boolean user notification field gift_subscription_purchase_notification to the exported User type and default factory data. Admin settings UI conditionally renders a toggle for user.gift_subscription_purchase_notification when Stripe and the giftSubscriptions feature are enabled. Ghost core email alert handling gained support for the gift-subscription-purchased alert key and staff email dispatch now queries that key. A unit test was updated to expect the new alert key. The Content API cleanup no longer deletes gift_subscription_redemption_notification.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding an email notifications toggle for gift subscription events, which is consistently reflected across all modified files.
Description check ✅ Passed The description is related to the changeset, referencing the issue BER-3523 and describing the addition of email notifications toggle for gift subscription events.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch BER-3523-add-settings-toggle

Comment @coderabbitai help to get the list of available commands and usage tips.

@mike182uk mike182uk force-pushed the BER-3523-add-db-columns branch from f65d37e to 8b11f20 Compare April 9, 2026 14:04
@mike182uk mike182uk force-pushed the BER-3523-add-settings-toggle branch from 7ce4c34 to 54e8c1a Compare April 9, 2026 14:05
@mike182uk mike182uk force-pushed the BER-3523-add-db-columns branch from 8b11f20 to e8e31a8 Compare April 9, 2026 14:12
@mike182uk mike182uk force-pushed the BER-3523-add-settings-toggle branch from 54e8c1a to 032805e Compare April 9, 2026 14:13
@mike182uk mike182uk force-pushed the BER-3523-add-db-columns branch from e8e31a8 to cd3a9a2 Compare April 9, 2026 14:32
@mike182uk mike182uk force-pushed the BER-3523-add-settings-toggle branch from 032805e to 1093508 Compare April 9, 2026 14:34
@mike182uk mike182uk force-pushed the BER-3523-add-db-columns branch from cd3a9a2 to ff8dae9 Compare April 9, 2026 14:42
@mike182uk mike182uk force-pushed the BER-3523-add-db-columns branch from ff8dae9 to 49501b5 Compare April 9, 2026 15:57
@mike182uk mike182uk force-pushed the BER-3523-add-settings-toggle branch from 1093508 to 3109fd9 Compare April 9, 2026 15:59
Base automatically changed from BER-3523-add-db-columns to main April 9, 2026 16:27
@mike182uk mike182uk force-pushed the BER-3523-add-settings-toggle branch 3 times, most recently from e6c0203 to 88a4a35 Compare April 9, 2026 20:29
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ghost/core/core/server/models/user.js (1)

499-523: ⚠️ Potential issue | 🟠 Major

Fail closed for unknown email alert types.

getEmailAlertUsers currently falls back to status:active when type is unrecognized, which can notify all active owners/admins and bypass per-event opt-in flags. With the new gift keys, a typo/regression in a caller becomes an over-notification path.

Suggested fix
 getEmailAlertUsers(type, options) {
     options = options || {};
-
-    let filter = 'status:active';
-    if (type === 'free-signup') {
-        filter += '+free_member_signup_notification:true';
-    } else if (type === 'paid-started') {
-        filter += '+paid_subscription_started_notification:true';
-    } else if (type === 'paid-canceled') {
-        filter += '+paid_subscription_canceled_notification:true';
-    } else if (type === 'mention-received') {
-        filter += '+mention_notifications:true';
-    } else if (type === 'milestone-received') {
-        filter += '+milestone_notifications:true';
-    } else if (type === 'donation') {
-        filter += '+donation_notifications:true';
-    } else if (type === 'recommendation-received') {
-        filter += '+recommendation_notifications:true';
-    } else if (type === 'gift-subscription-purchased') {
-        filter += '+gift_subscription_purchase_notification:true';
-    } else if (type === 'gift-subscription-redeemed') {
-        filter += '+gift_subscription_redemption_notification:true';
-    }
+    const notificationFieldByType = {
+        'free-signup': 'free_member_signup_notification',
+        'paid-started': 'paid_subscription_started_notification',
+        'paid-canceled': 'paid_subscription_canceled_notification',
+        'mention-received': 'mention_notifications',
+        'milestone-received': 'milestone_notifications',
+        'donation': 'donation_notifications',
+        'recommendation-received': 'recommendation_notifications',
+        'gift-subscription-purchased': 'gift_subscription_purchase_notification',
+        'gift-subscription-redeemed': 'gift_subscription_redemption_notification'
+    };
+
+    const notificationField = notificationFieldByType[type];
+    if (!notificationField) {
+        return Promise.resolve([]);
+    }
+
+    const filter = `status:active+${notificationField}:true`;
     const updatedOptions = Object.assign({}, options, {filter, withRelated: ['roles']});
     return this.findAll(updatedOptions).then((users) => {
         return users.toJSON().filter((user) => {
             return user?.roles?.some((role) => {
                 return ['Owner', 'Administrator'].includes(role.name);
             });
         });
     });
 },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ghost/core/core/server/models/user.js` around lines 499 - 523,
getEmailAlertUsers currently defaults to 'status:active' for unknown types which
risks over-notifying; update the function to validate the incoming type against
the known set (e.g., free-signup, paid-started, paid-canceled, mention-received,
milestone-received, donation, recommendation-received,
gift-subscription-purchased, gift-subscription-redeemed) and fail closed for
anything unrecognized by returning an empty result (e.g., return
Promise.resolve([])) or applying a filter that matches no users before calling
findAll; adjust the code that builds filter (variable filter) and updatedOptions
so unknown types do not fall through to the active-owner path and optionally
emit a warning log instead of querying with 'status:active'.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@ghost/core/core/server/models/user.js`:
- Around line 499-523: getEmailAlertUsers currently defaults to 'status:active'
for unknown types which risks over-notifying; update the function to validate
the incoming type against the known set (e.g., free-signup, paid-started,
paid-canceled, mention-received, milestone-received, donation,
recommendation-received, gift-subscription-purchased,
gift-subscription-redeemed) and fail closed for anything unrecognized by
returning an empty result (e.g., return Promise.resolve([])) or applying a
filter that matches no users before calling findAll; adjust the code that builds
filter (variable filter) and updatedOptions so unknown types do not fall through
to the active-owner path and optionally emit a warning log instead of querying
with 'status:active'.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 70dda4b7-9905-4500-8e72-42db2d671529

📥 Commits

Reviewing files that changed from the base of the PR and between e6c0203 and 88a4a35.

📒 Files selected for processing (6)
  • apps/admin-x-framework/src/api/users.ts
  • apps/admin-x-settings/src/components/settings/general/users/email-notifications-tab.tsx
  • apps/admin/test-utils/factories/user.ts
  • ghost/core/core/server/models/user.js
  • ghost/core/core/server/services/staff/staff-service-emails.js
  • ghost/core/test/unit/server/services/staff/staff-service.test.js
✅ Files skipped from review due to trivial changes (2)
  • ghost/core/test/unit/server/services/staff/staff-service.test.js
  • apps/admin/test-utils/factories/user.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • ghost/core/core/server/services/staff/staff-service-emails.js
  • apps/admin-x-framework/src/api/users.ts

@mike182uk mike182uk force-pushed the BER-3523-add-settings-toggle branch from 88a4a35 to 76a2df0 Compare April 13, 2026 09:06
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ghost/core/core/server/models/user.js (1)

495-497: ⚠️ Potential issue | 🟡 Minor

Update the type JSDoc union to reflect supported alert keys.

getEmailAlertUsers() now supports 'gift-subscription-purchased' (plus other existing keys), but the JSDoc @param union is out of date. Please sync it so the public contract is accurate.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ghost/core/core/server/models/user.js` around lines 495 - 497, The JSDoc for
getEmailAlertUsers is out of sync: update the `@param` type union (currently
{'free-signup'|'paid-started'|'paid-canceled'}) to include
'gift-subscription-purchased' and any other alert keys actually supported by the
getEmailAlertUsers implementation so the public contract matches the code;
modify the JSDoc on the getEmailAlertUsers function declaration accordingly to
list all supported alert key strings.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@ghost/core/core/server/models/user.js`:
- Around line 495-497: The JSDoc for getEmailAlertUsers is out of sync: update
the `@param` type union (currently {'free-signup'|'paid-started'|'paid-canceled'})
to include 'gift-subscription-purchased' and any other alert keys actually
supported by the getEmailAlertUsers implementation so the public contract
matches the code; modify the JSDoc on the getEmailAlertUsers function
declaration accordingly to list all supported alert key strings.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2857b251-2cc5-4e00-90d8-f74fdfd9563a

📥 Commits

Reviewing files that changed from the base of the PR and between 76a2df0 and ade86eb.

📒 Files selected for processing (5)
  • apps/admin-x-framework/src/api/users.ts
  • apps/admin-x-settings/src/components/settings/general/users/email-notifications-tab.tsx
  • apps/admin/test-utils/factories/user.ts
  • ghost/core/core/server/api/endpoints/utils/serializers/output/utils/clean.js
  • ghost/core/core/server/models/user.js
💤 Files with no reviewable changes (1)
  • ghost/core/core/server/api/endpoints/utils/serializers/output/utils/clean.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/admin-x-framework/src/api/users.ts
  • apps/admin/test-utils/factories/user.ts

@mike182uk mike182uk force-pushed the BER-3523-add-settings-toggle branch from ade86eb to 24d648b Compare April 13, 2026 11:33
@sonarqubecloud
Copy link
Copy Markdown

@mike182uk mike182uk merged commit 791bd60 into main Apr 13, 2026
81 of 83 checks passed
@mike182uk mike182uk deleted the BER-3523-add-settings-toggle branch April 13, 2026 13:19
franky19 pushed a commit to franky19/Ghost that referenced this pull request Apr 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants