Fixed expired complimentary members not triggering webhooks#28444
Fixed expired complimentary members not triggering webhooks#284449larsons wants to merge 1 commit into
Conversation
no ref Direct DB updates in worker jobs bypass model lifecycle events, so expiring a comped member updated access without emitting member.edited. This keeps workers model-free and adds a narrow worker-to-host bridge instead of initializing Ghost models inside the worker runtime.
WalkthroughThis PR introduces a worker-to-model-event bridge system for translating job worker messages into application domain events. A new 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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@ghost/core/core/server/services/jobs/worker-model-event-bridge.js`:
- Around line 62-64: The current validation uses a truthy guard so
message.options === null slips through and later causes an internal handler
error when accessing options.context; update the validation around
message.options (using the existing isObject helper) to explicitly reject
non-objects and null (e.g., change the check to ensure isObject(message.options)
is true or explicitly test message.options == null) so that the function returns
'Invalid options' for null/invalid payloads before reaching the code that reads
options.context.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 4c4e7238-1b92-4037-a86f-8ce1d2c41871
📒 Files selected for processing (7)
ghost/core/core/server/services/jobs/job-service.jsghost/core/core/server/services/jobs/worker-model-event-bridge.jsghost/core/core/server/services/members/jobs/clean-expired-comped.jsghost/core/test/unit/server/services/jobs/job-service.test.jsghost/core/test/unit/server/services/jobs/worker-model-event-bridge.test.jsghost/core/test/unit/server/services/members/clean-expired-comped.test.jsghost/core/test/unit/server/services/webhooks/serialize.test.js
| if (message.options && !isObject(message.options)) { | ||
| return 'Invalid options'; | ||
| } |
There was a problem hiding this comment.
Reject options: null during validation to avoid false handler-error reporting
Line 62 uses a truthy guard, so options: null bypasses validation and later throws at Line 103 when reading options.context, which gets reported as an internal handler error instead of an invalid payload.
Proposed fix
- if (message.options && !isObject(message.options)) {
+ if (message.options !== undefined && !isObject(message.options)) {
return 'Invalid options';
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (message.options && !isObject(message.options)) { | |
| return 'Invalid options'; | |
| } | |
| if (message.options !== undefined && !isObject(message.options)) { | |
| return 'Invalid options'; | |
| } |
🤖 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/core/server/services/jobs/worker-model-event-bridge.js` around
lines 62 - 64, The current validation uses a truthy guard so message.options ===
null slips through and later causes an internal handler error when accessing
options.context; update the validation around message.options (using the
existing isObject helper) to explicitly reject non-objects and null (e.g.,
change the check to ensure isObject(message.options) is true or explicitly test
message.options == null) so that the function returns 'Invalid options' for
null/invalid payloads before reaching the code that reads options.context.
Summary
model-eventworker messages through the bridge without dispatching them as raw domain eventsmember.editedmodel-event messages fromclean-expired-compedafter direct DB cleanupTest notes
pnpm --dir ghost/core test:single test/unit/server/services/jobs/job-service.test.jspnpm --dir ghost/core test:single test/unit/server/services/jobs/worker-model-event-bridge.test.jspnpm --dir ghost/core test:single test/unit/server/services/members/clean-expired-comped.test.jspnpm --dir ghost/core test:single test/unit/server/services/webhooks/serialize.test.jspnpm --dir ghost/core exec eslint core/server/services/jobs/job-service.js core/server/services/jobs/worker-model-event-bridge.js core/server/services/members/jobs/clean-expired-comped.js test/unit/server/services/jobs/job-service.test.js test/unit/server/services/jobs/worker-model-event-bridge.test.js test/unit/server/services/members/clean-expired-comped.test.js test/unit/server/services/webhooks/serialize.test.js