refs https://github.com/TryGhost/Team/issues/1552
- The API doesn't enforce a unique sort order but we infer the "default newsletter" based on ordering so we need to ensure a consistent and deterministic ordering behaviour
refs https://github.com/TryGhost/Team/issues/1524
- We need to fetch the post newsletter to grab the slug as it's needed for the member NQL filter.
- We can then use the newsletter slug and append it in the existing member NQL filter.
- Removed `subscribed:true` when an email is sent to a newsletter and replaced it with the newsletter id
- Added `status:-free` when an email is sent to a newsletter with `visibility` set to `paid`
- Added tests what happens when you publish without newsletter_id
- Added tests what happens when you publish with newsletter_id
Co-authored-by: Simon Backx <simon@ghost.org>
refs https://github.com/TryGhost/Team/issues/1524
- This enables admins in the ghost admin to have an overview of the total posts/members associated with a newsletter.
- Follows the `?include=count.x` convention used by other resources
Closes https://github.com/TryGhost/Team/issues/1508
Refs https://github.com/TryGhost/Ghost/pull/14468
- Maps existing subscribers to the default newsletter
A note on performance:
We loop over the rows in a potentially large table (members) but I've minimised the impact by limiting the columns we fetch. The alternative is a raw SQL query like the one below: the SQL version takes ~0.9s vs ~1.1s for the migration (my laptop, ~30k members). The disadvantage of the raw SQL implementation is the approximation of the ObjectID (instead of a legit bson ID) which isn't sequential and may impact index size/performance.
```sql
insert into members_newsletters (id, member_id, newsletter_id)
select
substr(replace(uuid(),'-',''),1,24),
id,
'62595dcbfad4e031d85d166f'
from members
where members.subscribed=true;
```
refs https://github.com/TryGhost/Team/issues/1495
- removes subscription from all newsletters for a member on click of unsubscribe link in email
- allows the new multiple newsletter system to work with existing unsubscribe flow
refs https://github.com/TryGhost/Team/issues/1478
The `newsletter_id` is nullable for now to remain compatible until we have a proper data migration + updated code to set it on inserts
refs https://github.com/TryGhost/Team/issues/1473
- Added the default newsletter
- We use the title to populate the newsletter same, slug and sender name
- We use the description to populate the newsletter description
- We use the global design settings to populate the corresponding newsletter design settings
Co-authored-by: Matt Hanley <git@matthanley.co.uk>
refs https://github.com/TryGhost/Team/issues/1532
- Added before the migration in https://github.com/TryGhost/Ghost/pull/14468 to populate the default newsletter
- The fixture for the default newsletter has a different value than the model and schema default
- This is because by default the newsletter name is the same as the site title, and the site title is already shown
refs https://github.com/TryGhost/Toolbox/issues/280
- When passing the sendEmail parameter with a boutnd 'send' method the e2e tests were failing becuase mock mailer did not pick up the send method. Using this slightly more verbose implementation as it "just works". Could be rewritten into something nicer if there's such a need in the future
refs https://github.com/TryGhost/Toolbox/issues/280
- ctd of putting pieces together to allow Ghost notifying owner and admin users about version mismatch errors
- The `@tryghost/mw-api-version-mismatch` in a combination with api version compatibility service make the whole notification process play nicely :)
- The flow of the logic from the request to a sent notification email is following:
1. Request comes is with an Accept-Version header that's behind current Ghost version and is not supported
2. mw-error-handler middleware's 'resourceNotFound' detects such request and returns a 406 with a special 'code' identifying if the version of the client is ahead or behind
3. mw-api-version-mismatch intercepts the 406 request with "code === 'UPDATE_CLIENT'` and calls up APIVersionCompatibilityService
4. emails are sent out to active owner and admin users
- The above flow is also illustratd in the e2e tests that come with the changeset
refs https://github.com/TryGhost/Toolbox/issues/280
- This is continuation of putting pieces together to allow Ghost notifying owner and admin users about version mismatch errors
- This changeset adds the api-version-compatibility intialization during the boot (needed to be able to pospone the send email initialization so that it's testeable from the e2e tests)
- There's also a data service which handles fetching/saving notifications and fetching emails of users that should be notified
refs https://github.com/TryGhost/Toolbox/issues/292
- When version missmatch handling is done in Ghost we need to store the 'Accept-Version' header values that have been already processed in the past (to avoid sending notifications about the same mismatch multiple times)
- The `version_notifications` will be storing an array with handled versions like so: `['v3.44', 'v4.23', 'v4.39']`.
- The emailing logic and processing is slightly similar to how "notification" key is handled, that's why I've placed the definition of this new key close by.
refs https://github.com/TryGhost/Team/issues/1520
- Sets the `offer_id` in the `members_stripe_customers_subscriptions` table based on the `offer_redemptions` that have the same tier and cadence
- We currently use the same subscription <-> offer linking when viewing a member
- The MySQL query is quite optimized in a single UPDATE query, but in SQLite we'll need to run (maximum) one UPDATE query for every offer (not per subscription).
- Best to merge this migration in 4.x (not in 5.0) because it is better (less error prone) to run this migration before starting to fill the offer_id field for updated migrations instead of after (https://github.com/TryGhost/Ghost/pull/14488)
- We need the SQLite migration for sites that will only migrate to MySQL at 5.0
refs https://github.com/TryGhost/Team/issues/1533
- Retrieves one newsletter
- Makes the newsletter resource consistent with the other resources
- Solves an issue with the admin expecting the route to exist
refs https://github.com/TryGhost/Team/issues/1533
- Needed to create the read newsletter endpoint to make the newsletter resource more consistent with the other resources
- Read is available to admins like other newsletter actions
- This cors middleware function has been stuck at the top of the site file for a while
- Move it to it's own file in keeping with our usual patterns for middleware
refs https://github.com/TryGhost/Team/issues/1519
Migration that adds the (nullable) offer_id column to members_stripe_customers_subscriptions.
- New reliable way to know which offer is active for a given subscription (currently we compare the tier and cadence in offer redemptions)
- We'll create a separate migration to backfill all the offer_ids, but only after we updated the code to also store them correctly for new or updated subscriptions (https://github.com/TryGhost/Team/issues/1520)
- Allows us to backfill the MRR of all subscriptions to account for forever offers
refs TryGhost/Team#1513
- nullable `sender_name` allows us to use auto fallback of site title for sender name without setting any explicit value for it.
refs https://github.com/TryGhost/Toolbox/issues/227
- The convention across the codebase is to define headers with capitalized first letters. This change does not affect the output though as all headers are served lowercased anyway.
- Might be a good idea to make all headers lowercased one day to match the casing with the outputs
refs https://github.com/TryGhost/Team/issues/1490
- adds intermediary newsletter pref selection page to signup flows in case a site has multiple newsletters
- for members signing up as free via magic link
- for members signing up as paid via stripe checkout
- for members signing up as paid via offer url
refs https://github.com/TryGhost/Team/issues/1502
- Support the `newsletter_id` only when sending a newsletter
- Default to the default newsletter when `newsletter_id` isn't specified
- Ignore the `newsletter_id` parameter when passed in the post body
refs https://github.com/TryGhost/Team/issues/1504
- The permissions were missing in the fixture file
- This caused some Ghost installs to not have the right permissions
- This is fixed by adding the missing permissions to the fixture file and creating a migration to resolve the missing permissions
refs https://github.com/TryGhost/Team/issues/1484
While sending a post to a specific newsletter, we'll need to get list/count of members eligible to receive the post. This change enables members admin API to filter list of members on specific newsletter by their slug.
closes https://github.com/TryGhost/Team/issues/1491
With multiple newsletters feature, a site should always have at-least one newsletter by default. Also, as with the default product, the default newsletter also needs to be renamed to the site title during the setup flow.
- adds default newsletter to main and test fixtures
- updates setup flow to rename newsletter name and sender name to site title
- updates model to extend default value for fields
- updates test
refs https://github.com/TryGhost/Team/issues/1457
We want to save the MRR with a subscription to simplify the calculation of the total MRR once, in 5.0, we also take 'forever' offers into account into the MRR (so we can just SUM the MRR of all subscriptions).
- Sets the MRR to 0 for now.
- Separate commit will fill in all the values in a data migration, but this needs to get merged first because we need this new column in order to update the members-api package (so we already save the MRR before doing the data migration).
- Updated `test/e2e-api/admin/legacy-members.test.js` with improved body assertions.
refs https://github.com/TryGhost/Team/issues/1302
We do not want to update MRR calculations until 5.0 - so will be adding
a separate migration to populate the mrr_delta column for 5.0
We've only added events for non-expired subscriptions as this is simpler
and won't impact the mrr events when mrr_delta is updated