Conversation
WalkthroughReworked getSubscriptionEvents to stop removing the helper relation from the in-memory Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
75e6850 to
17d168f
Compare
17d168f to
e7f993c
Compare
ref https://linear.app/ghost/issue/BER-3542 - when a gift member continued with a paid trial, the activity feed correctly logged "Continued paid subscription after gift" - after the trial converted on first payment, the same entry was reverting to "Started paid subscription" - root cause: getSubscriptionEvents iterated paid-subscription rows newest-first and deleted the paidStatusEvent helper relation from the shared, eager-loaded SubscriptionCreatedEvent instance after computing previous_status - once a newer 'updated' row was added on trial→active, it processed first and wiped the relation, so the older 'created' row read previous_status=null on the next iteration - removed the in-loop delete; the activity-feed serializer already strips subscriptionCreatedEvent from the response, so no leak is reintroduced - added a regression test that mirrors Bookshelf's shared-instance behaviour and asserts previous_status='gift' survives across iterations
e7f993c to
9b6482d
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
ghost/core/test/unit/server/services/members/members-api/repositories/event-repository.test.js (1)
760-871: 💤 Low valueSolid regression coverage; consider also asserting the
updatedrow.The mock faithfully reproduces Bookshelf's shared-instance behaviour for
subscriptionCreatedEvent(same reference returned to both rows), and the final assertion on Line 870 nicely guarantees the shared origin is left unmutated — exactly the invariant the production fix establishes. Ordering the rows asupdatedthencreatedcorrectly mirrors the buggy iteration order.A small enhancement to consider: the test only asserts
previous_statusfor thecreatedrow. Addingassert.equal(updated.data.previous_status, 'gift');would tighten the regression so a future "skip previous_status for non-created rows" change couldn't accidentally bypass the check. Optional.One minor cleanup:
makeRelated/sharedRelated(Lines 766–773) are unreachable in this test becauserelations(Lines 776–779) already contains bothsubscriptionCreatedEventandstripeSubscription, so the?? sharedRelated(name)fallback never fires. You can dropmakeRelated/sharedRelatedwithout changing behaviour.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@ghost/core/test/unit/server/services/members/members-api/repositories/event-repository.test.js` around lines 760 - 871, The test getSubscriptionEvents's regression should both assert the updated row's previous_status and remove dead helper code: add an assertion similar to assert.equal(updated.data.previous_status, 'gift') in the "preserves previous_status..." it block so the updated row is explicitly checked, and delete the unused helper functions makeRelated and sharedRelated (and their references) from buildModels since relations already contains subscriptionCreatedEvent and stripeSubscription and the fallback never runs; update buildModels to rely only on the relations object and toJSON as it currently does.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In
`@ghost/core/test/unit/server/services/members/members-api/repositories/event-repository.test.js`:
- Around line 760-871: The test getSubscriptionEvents's regression should both
assert the updated row's previous_status and remove dead helper code: add an
assertion similar to assert.equal(updated.data.previous_status, 'gift') in the
"preserves previous_status..." it block so the updated row is explicitly
checked, and delete the unused helper functions makeRelated and sharedRelated
(and their references) from buildModels since relations already contains
subscriptionCreatedEvent and stripeSubscription and the fallback never runs;
update buildModels to rely only on the relations object and toJSON as it
currently does.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 267f7008-f99e-4150-8da4-4f1904321b47
📒 Files selected for processing (2)
ghost/core/core/server/services/members/members-api/repositories/event-repository.jsghost/core/test/unit/server/services/members/members-api/repositories/event-repository.test.js
closes https://linear.app/ghost/issue/BER-3542
Fixes the member activity feed entry for gift members who continue into a paid subscription.
When a gift member upgraded to a paid subscription, the subscription event initially had enough context to show
continued paid subscription after gift. However,getSubscriptionEvents()deleted the eager-loadedpaidStatusEventrelation from the sharedSubscriptionCreatedEventBookshelf model while serializing the first event row.Because multiple
MemberPaidSubscriptionEventrows can share the sameSubscriptionCreatedEventinstance, later rows could lose access topaidStatusEvent. That causedprevious_statusto becomenull, and the activity feed could revert to the genericstarted paid subscriptionwording after the next payment/update event.This change:
paidStatusEventavailable on the shared relation while derivingprevious_statussubscriptionCreatedEvent.paidStatusEventonly from the serialized event payload