refs https://github.com/TryGhost/Team/issues/2078
These events are all required for other parts of the Ghost system to stay in
sync. The events on each Tier object will be dispatched by the TierRepository
once they've been persisted.
TierCreatedEvent - generate Stripe Products & Prices
TierNameChangeEvent - update Stripe Products
TierPriceChangeEvent - update Stripe Products & Prices
TierArchivedEvent - update the Portal settings for visible tiers
- disable Stripe Products & Prices
TierActivatedEvent - enable Stripe Products & Prices
refs 82ed10473b
refs https://github.com/TryGhost/Team/issues/1869
- getDefaultProduct has unified logic across different places (see refed commit). It is recommended to use instead of writing custom queries prone to mistakes.
- Also added more readable name to the possible error message thrown by setComplimentarySubscription
closes https://github.com/TryGhost/Team/issues/1869
- When there were "archived" tiers in the system the importer incorrectly fetched them instead of only taking "active" ones into account. The "getDefaultProduct" on product repository does exactly that.
- Additionally, reusing the "getDefaultProduct" makes testing the importer slightly less complex.
refs https://github.com/TryGhost/Team/issues/1869
- There are multiple places in the codebase fetching "default product". The code is slightly divergent in each one of them and has been a source of bugs (like the one referenced). Having the logic captured in one place will allow reducing the code duplication, making code less bug prone, and making testing the modules dependent on the "setDefaultProduct" method easier
refs https://github.com/TryGhost/Team/issues/2078
The check for creating free Tiers needs to be explicit, rather than implicit
because the type is optional, we only want to error if it is explicitly passed
as "free", not if it is missing as "paid".
refs https://github.com/TryGhost/Team/issues/2078
Having to map between snake_case and camelCase was becoming confusing, so this
updates the Tier object to exclusively use camelCase, and the snake_case for the
API can be handled by the serializer/mapper or at the controller level.
refs https://github.com/TryGhost/Team/issues/2078
This removes the burden from the Tier object, and allows us to reuse
the existing slug generation implementation we have in our bookshelf
models.
refs https://github.com/TryGhost/Team/issues/2034
- this table will be used to link Stripe subscriptions to Ghost
subscriptions via a foreign key that we add at a later point
- this also includes `constraintName` as the auto-generated one would be
too long for MySQL 8
refs https://github.com/TryGhost/Team/issues/2104
- adds edit permissions for links endpoints to fixtures
- new `bulkEdit` endpoint will use the permissions and allow fixing newsletter links via Admin
refs 5fcf5098a8
- links browse endpoint had permissions switched off unintentionally and was also missing the necessary permissions in fixtures.
- enables permissions for browse endpoint and adds migration insert permissions in DB
- fixes an edge case where if a site has no unavailable sources in a particular period, it broke the table view as the `Others` data doesn't get fetched
fixes https://github.com/TryGhost/Team/issues/2090
- This changes how sentiment is exposed in the API. Now it is exposed as a `sentiment` relation, directly on the model (no longer in counts). Internally we still use `count.sentiment`.
- Content API users (and themes) can include the 'sentiment' relation and order by sentiment.
- Updated Admin to use sentiment instead of count.sentiment
refs https://github.com/TryGhost/Team/issues/2116
- wires handling of success and error messages on editing a newsletter link
- has the update api commented out temporarily to mock the changes
closesTryGhost/Team#2080
- If the post was published and emailed the link leads the user to the
post.
- If the post was just emailed the link leads the user to the home page.
closes https://github.com/TryGhost/Toolbox/issues/430
- The members importer used to import all fields present in the uploaded CSV if the headers match, even if they're not mapped in the UI. This behavior has lead to have misleading consequences and "hidden" features. For example, if the field was present but intentionally left as "Not imported" in the UI the field would still get imported.
- Having a strict list of supported import fields also allows for manageable long-term maintenance of the CSV Import API and detect/communicate changes when they happen.
- The list of the current default field mapping is:
email: 'email',
name: 'name',
note: 'note',
subscribed_to_emails: 'subscribed',
created_at: 'created_at',
complimentary_plan: 'complimentary_plan',
stripe_customer_id: 'stripe_customer_id',
labels: 'labels',
products: 'products'
refs https://github.com/TryGhost/Toolbox/issues/430
- Previously the CSV parser had "map whatever you can and pass on unknown properties further" approach to CSV parsing. This logic has led to unwanted fields leaking through CSV imports - messy, dangerous.
- The strict mapping rules act as a "validator" to the user input, only passing through the fields we expect explicitly - safer clean cut solution with no unintended side-effects.
refs https://github.com/TryGhost/Toolbox/issues/430
- To be able to introduce strict mapping rules (exclude unknown fields) we need to control the CSV header mapping on the importer level. This change moves the configuration up from CSV parser to the importer
- Also adds tests covering correct inserts for specially treated "subscribed_to_emails" field
refs https://github.com/TryGhost/Toolbox/issues/430
- "perform()" is what gets executed by the import job for both immediate import and "inline job" import. Testing it on granular level will allow to change it with more confidence when introducing strict field mapping rules
refs https://github.com/TryGhost/Toolbox/issues/430
- Importer code was filled with an unnecessarily complex "job" object that was passed around. It had an "id" property, which confusingly was a path to a file at all times.
- Simplified the logic significantly by keeping and passing around the path to a "prepared" members CSV.
refs https://github.com/TryGhost/Toolbox/issues/430
- The job "status" is never anything different than "pending" and never leaves the module itself. It's an outdated concept that only takes up lines of code!
refs https://github.com/TryGhost/Toolbox/issues/430
refs https://github.com/TryGhost/Ghost/issues/14882
- The MembersCSVImporter constructor is way to complex and needs refactoring. This complexity makes initialization in tests too bulky and makes tests hard to read.
- Having a builder method is a stopgap solution to avoid going into MembersCSVImporter refactoring too deep.
refs https://github.com/TryGhost/Toolbox/issues/430
refs https://github.com/TryGhost/Ghost/issues/14882
- Having an explicit mappings passed into the members CSV parser makes it easier to control and understand the transforms for package clients
- Eventually the parser will receive a strict map with the fields it should parse - skipping all unknown & unmapped fields
refs https://github.com/TryGhost/Toolbox/issues/430
- Not having any extra logic in the mapper will allow to have a generalized "mapping" concept for CSV input serialization
- This is groundwork for stricter header value filtering on the parsing stage