Skip to content

Changed member welcome email job to run based on config#21

Open
tomerqodo wants to merge 6 commits into
qodo_action_req_base_changed_member_welcome_email_job_to_run_based_on_config_pr6from
qodo_action_req_head_changed_member_welcome_email_job_to_run_based_on_config_pr6
Open

Changed member welcome email job to run based on config#21
tomerqodo wants to merge 6 commits into
qodo_action_req_base_changed_member_welcome_email_job_to_run_based_on_config_pr6from
qodo_action_req_head_changed_member_welcome_email_job_to_run_based_on_config_pr6

Conversation

@tomerqodo
Copy link
Copy Markdown

Benchmark PR from agentic-review-benchmarks#6

@qodo-code-review
Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (1) 📎 Requirement gaps (0)

Grey Divider


Action required

1. var member used 📘 Rule violation ✓ Correctness
Description
var member; is introduced in MemberRepository, violating the requirement to use block-scoped
  let/const instead of var.
• Using var can cause hoisting and scoping surprises, increasing the risk of subtle runtime bugs
  in async-heavy repository code.
Code

ghost/core/core/server/services/members/members-api/repositories/MemberRepository.js[340]

+        var member;
Evidence
PR Compliance ID 24 prohibits var declarations. The new code explicitly declares var member; in
the modified section.

AGENTS.md
ghost/core/core/server/services/members/members-api/repositories/MemberRepository.js[339-342]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`MemberRepository` introduces `var member;`, which violates the codebase requirement to use `let`/`const` and risks function-scoped leakage/hoisting issues.

## Issue Context
This occurs in the member creation flow where variables may be used across async boundaries.

## Fix Focus Areas
- ghost/core/core/server/services/members/members-api/repositories/MemberRepository.js[339-342]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Welcome job not scheduled 🐞 Bug ✓ Correctness
Description
• The scheduling guard was inverted (hasScheduled.processOutbox instead of
  !hasScheduled.processOutbox), so on first boot the recurring job is never added.
• As a result, welcome-email outbox entries will never be processed, effectively disabling the
  feature even when configured.
• Because scheduling happens during background service init, there is no later retry point to
  recover from this.
Code

ghost/core/core/server/services/member-welcome-emails/jobs/index.js[R15-18]

+        if (hasScheduled.processOutbox && !process.env.NODE_ENV.startsWith('test')) {
            jobsService.addJob({
                at: '0 */5 * * * *',
                job: path.resolve(__dirname, 'process-outbox.js'),
Evidence
hasScheduled.processOutbox starts false, but the new condition only schedules when it is already
true, so the addJob call is skipped forever. Boot only initializes the service once in non-test
environments, so the missed schedule is not retried.

ghost/core/core/server/services/member-welcome-emails/jobs/index.js[5-26]
ghost/core/core/server/services/member-welcome-emails/index.js[3-12]
ghost/core/core/boot.js[403-424]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The recurring job for processing member welcome email outbox entries is never scheduled because the guard condition was inverted.

### Issue Context
`hasScheduled.processOutbox` initializes to `false`, but scheduling currently only happens when it is `true`, so `jobsService.addJob()` never runs.

### Fix Focus Areas
- ghost/core/core/server/services/member-welcome-emails/jobs/index.js[11-25]

Suggested change:
- Replace `if (hasScheduled.processOutbox && ...)` with `if (!hasScheduled.processOutbox && ...)`.
- (Optional hardening) use `process.env.NODE_ENV?.startsWith('test')` or rely on the existing boot-level test guard to avoid duplicating the env check.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Outbox gating uses OR 🐞 Bug ⛯ Reliability
Description
• Member creation now enters the outbox-writing path when either the config is set OR the source is
  allowed; since the allowed source list includes normal member signups, this creates outbox entries
  even when the config is empty/undefined.
• This contradicts the updated tests, which expect no outbox entry when the config is not set.
• It also conflicts with the sending code, which throws if memberWelcomeEmailTestInbox is missing,
  causing failures/retries (or a growing backlog if the processor job is not running).
Code

ghost/core/core/server/services/members/members-api/repositories/MemberRepository.js[R340-342]

+        var member;
+        const welcomeEmailConfig = config.get('memberWelcomeEmailTestInbox');
+        if (welcomeEmailConfig || WELCOME_EMAIL_SOURCES.includes(source)) {
Evidence
WELCOME_EMAIL_SOURCES includes 'member', so the current `welcomeEmailConfig ||
WELCOME_EMAIL_SOURCES.includes(source)` condition is true for normal signups even when the config is
the default empty string. The mail sender explicitly requires the config and throws when it is
absent, and the updated tests assert that no outbox entry should be created when the config is not
set—indicating the condition should be welcomeEmailConfig && allowedSource.

ghost/core/core/server/services/members/members-api/repositories/MemberRepository.js[28-28]
ghost/core/core/server/services/members/members-api/repositories/MemberRepository.js[339-363]
ghost/core/core/shared/config/defaults.json[304-306]
ghost/core/core/server/services/member-welcome-emails/jobs/lib/send-member-welcome-email.js[29-36]
ghost/core/test/integration/services/member-welcome-emails.test.js[52-65]
ghost/core/test/unit/server/services/members/members-api/repositories/MemberRepository.test.js[554-569]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Outbox entries for welcome emails are created even when the feature is effectively disabled (config unset), because an OR condition is used.

### Issue Context
- `WELCOME_EMAIL_SOURCES` includes `member`, so normal signup sources make the OR condition true even if the config is empty.
- The sender (`send-member-welcome-email`) throws if the config is missing.
- Tests explicitly expect no outbox entry when the config is not set.

### Fix Focus Areas
- ghost/core/core/server/services/members/members-api/repositories/MemberRepository.js[339-378]

Suggested change:
- Replace:
 - `if (welcomeEmailConfig || WELCOME_EMAIL_SOURCES.includes(source))`
- With:
 - `if (welcomeEmailConfig && WELCOME_EMAIL_SOURCES.includes(source))`
- Consider renaming `welcomeEmailConfig` to something like `testInbox` and explicitly checking for non-empty string if needed.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



ⓘ The new review experience is currently in Beta. Learn more

Qodo Logo

const memberAddOptions = {...(options || {}), withRelated};
let member;
if (this._labsService.isSet('welcomeEmails') && WELCOME_EMAIL_SOURCES.includes(source)) {
var member;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. var member used 📘 Rule violation ✓ Correctness

var member; is introduced in MemberRepository, violating the requirement to use block-scoped
  let/const instead of var.
• Using var can cause hoisting and scoping surprises, increasing the risk of subtle runtime bugs
  in async-heavy repository code.
Agent prompt
## Issue description
`MemberRepository` introduces `var member;`, which violates the codebase requirement to use `let`/`const` and risks function-scoped leakage/hoisting issues.

## Issue Context
This occurs in the member creation flow where variables may be used across async boundaries.

## Fix Focus Areas
- ghost/core/core/server/services/members/members-api/repositories/MemberRepository.js[339-342]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +15 to 18
if (hasScheduled.processOutbox && !process.env.NODE_ENV.startsWith('test')) {
jobsService.addJob({
at: '0 */5 * * * *',
job: path.resolve(__dirname, 'process-outbox.js'),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Welcome job not scheduled 🐞 Bug ✓ Correctness

• The scheduling guard was inverted (hasScheduled.processOutbox instead of
  !hasScheduled.processOutbox), so on first boot the recurring job is never added.
• As a result, welcome-email outbox entries will never be processed, effectively disabling the
  feature even when configured.
• Because scheduling happens during background service init, there is no later retry point to
  recover from this.
Agent prompt
### Issue description
The recurring job for processing member welcome email outbox entries is never scheduled because the guard condition was inverted.

### Issue Context
`hasScheduled.processOutbox` initializes to `false`, but scheduling currently only happens when it is `true`, so `jobsService.addJob()` never runs.

### Fix Focus Areas
- ghost/core/core/server/services/member-welcome-emails/jobs/index.js[11-25]

Suggested change:
- Replace `if (hasScheduled.processOutbox && ...)` with `if (!hasScheduled.processOutbox && ...)`.
- (Optional hardening) use `process.env.NODE_ENV?.startsWith('test')` or rely on the existing boot-level test guard to avoid duplicating the env check.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +340 to +342
var member;
const welcomeEmailConfig = config.get('memberWelcomeEmailTestInbox');
if (welcomeEmailConfig || WELCOME_EMAIL_SOURCES.includes(source)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

3. Outbox gating uses or 🐞 Bug ⛯ Reliability

• Member creation now enters the outbox-writing path when either the config is set OR the source is
  allowed; since the allowed source list includes normal member signups, this creates outbox entries
  even when the config is empty/undefined.
• This contradicts the updated tests, which expect no outbox entry when the config is not set.
• It also conflicts with the sending code, which throws if memberWelcomeEmailTestInbox is missing,
  causing failures/retries (or a growing backlog if the processor job is not running).
Agent prompt
### Issue description
Outbox entries for welcome emails are created even when the feature is effectively disabled (config unset), because an OR condition is used.

### Issue Context
- `WELCOME_EMAIL_SOURCES` includes `member`, so normal signup sources make the OR condition true even if the config is empty.
- The sender (`send-member-welcome-email`) throws if the config is missing.
- Tests explicitly expect no outbox entry when the config is not set.

### Fix Focus Areas
- ghost/core/core/server/services/members/members-api/repositories/MemberRepository.js[339-378]

Suggested change:
- Replace:
  - `if (welcomeEmailConfig || WELCOME_EMAIL_SOURCES.includes(source))`
- With:
  - `if (welcomeEmailConfig && WELCOME_EMAIL_SOURCES.includes(source))`
- Consider renaming `welcomeEmailConfig` to something like `testInbox` and explicitly checking for non-empty string if needed.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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