Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
Disabled knowledge base sources:
📝 WalkthroughWalkthroughAdds a require-signup experiment and helpers on the User model, a per-level Changes
Sequence Diagram(s)sequenceDiagram
participant CV as CampaignView
participant HM as HeroVictoryModal
participant User as UserModel
participant Exp as ExperimentService
participant UI as CreateAccountModal
CV->>User: onClickStartLevel(level) — check level.requiresSignUp && me.isAnonymous()
alt anonymous && requiresSignUp
User->>Exp: getOrStartRequireSignupExperimentValue(CAMPAIGN)
Exp-->>User: "beta" / "control" / null
alt "beta"
CV->>UI: promptForSignup({accountRequiredMessage})
UI-->>CV: modal opened (stop start flow)
else
CV->>CV: proceed with normal start flow
end
else
CV->>CV: proceed with normal start flow
end
HM->>User: onClickContinue — determine next/practice level requiresSignUp
alt anonymous && requiresSignUp
User->>Exp: getOrStartRequireSignupExperimentValue('junior')
Exp-->>User: "beta" / "control" / null
alt "beta"
HM->>UI: open CreateAccountModal(accountRequiredMessage)
UI-->>HM: modal opened (stop navigation)
else
HM->>HM: continue navigation
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (2 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: 2
🧹 Nitpick comments (1)
app/schemas/models/level.js (1)
436-436: MakeallowAnonymousdefault explicit for schema clarity.Line [436] currently relies on implicit falsy handling downstream; adding an explicit default makes intent clearer and avoids ambiguous editor behavior.
🧹 Suggested tweak
- allowAnonymous: { title: 'Allow Anonymous Play', description: 'Whether this level is available to anonymous user', type: 'boolean', inEditor: 'codecombat' }, + allowAnonymous: { title: 'Allow Anonymous Play', description: 'Whether this level is available to anonymous users', type: 'boolean', default: false, inEditor: 'codecombat' },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/schemas/models/level.js` at line 436, The allowAnonymous property in the Level schema should have an explicit default to avoid implicit falsy assumptions; update the schema definition for allowAnonymous (the property currently titled 'Allow Anonymous Play' in the exported Level model) to include default: false so the editor and validators receive an explicit value and downstream code behaves predictably.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/schemas/models/campaign.schema.js`:
- Around line 271-272: The CampaignSchema is copying
LevelSchema.properties.classroomSub which contains a $ref to
'#/definitions/classroomSub' that CampaignSchema does not define, causing a
dangling reference; fix by replacing the cloned reference with an inline schema
or adding the missing definition: either (A) inline the actual classroomSub
schema where you currently copy LevelSchema.properties.classroomSub (remove the
$ref and expand its properties) or (B) add a definitions.classroomSub entry to
CampaignSchema matching the referenced schema so the $ref resolves; locate the
cloning code that references LevelSchema.properties.classroomSub and update it
to one of these two options (ensure symbols: LevelSchema.properties.classroomSub
and CampaignSchema are updated).
In `@app/views/play/CampaignView.js`:
- Around line 1931-1936: The code currently does "return this.promptForSignup()"
inside the me.isAnonymous() / requireSignup check which can block level start
when promptForSignup() is a no-op; instead invoke promptForSignup() without
unconditionally returning and only short-circuit if the call explicitly signals
a blocking action. Change the block around me.isAnonymous(),
me.getOrStartRequireSignupExperimentValue(), and level.allowAnonymous so you
call this.promptForSignup() and then "if (this.promptForSignup()) return;" (or
store the result in a var and return only when truthy) rather than always
returning its result.
---
Nitpick comments:
In `@app/schemas/models/level.js`:
- Line 436: The allowAnonymous property in the Level schema should have an
explicit default to avoid implicit falsy assumptions; update the schema
definition for allowAnonymous (the property currently titled 'Allow Anonymous
Play' in the exported Level model) to include default: false so the editor and
validators receive an explicit value and downstream code behaves predictably.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 255faf8f-44b5-48a8-ac15-8a63f6a9e808
📒 Files selected for processing (4)
app/models/User.jsapp/schemas/models/campaign.schema.jsapp/schemas/models/level.jsapp/views/play/CampaignView.js
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/views/play/level/modal/HeroVictoryModal.js`:
- Around line 621-627: The current gating logic in HeroVictoryModal.js checks
this.nextLevel before honoring options.sendToPracticeLevel, which can read
allowAnonymous from the wrong destination; update the branch so that when
options.sendToPracticeLevel is true and this.practiceLevel?.get('slug') exists
you set allowAnonymous = this.practiceLevel.get('allowAnonymous'), otherwise
fall back to this.nextLevel?.get('slug') and its allowAnonymous; keep the
existing product check for 'codecombat-junior' and ensure you use safe null
checks (this.practiceLevel and this.nextLevel) when reading
get('allowAnonymous') so the practice path is chosen when sendToPracticeLevel is
true.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: fa62504e-7c2a-4505-ad71-af88c4bbe671
📒 Files selected for processing (4)
app/locale/zh-HANS.jsapp/models/User.jsapp/views/play/CampaignView.jsapp/views/play/level/modal/HeroVictoryModal.js
✅ Files skipped from review due to trivial changes (2)
- app/views/play/CampaignView.js
- app/models/User.js
mrfinch
left a comment
There was a problem hiding this comment.
When the signup modal opens with the date page, can u add these message there:
You've unlocked the next level! Create a free account to save your progress and continue your coding journey.
below Parents, use your own birthdate. probably passing via: accountRequiredMessage
There was a problem hiding this comment.
♻️ Duplicate comments (1)
app/views/play/CampaignView.js (1)
1931-1936:⚠️ Potential issue | 🟠 MajorAvoid hard-return when signup prompt is suppressed.
On Line 1935, returning
this.promptForSignup(...)can block level start whenpromptForSignupno-ops (HoC/noAuth paths) and returns nothing.Proposed fix
if (!level.allowAnonymous && me.isAnonymous()) { const CAMPAIGN = this.campaign?.get('name')?.toLowerCase() || this.terrain const requireSignup = me.getOrStartRequireSignupExperimentValue?.(CAMPAIGN) if (requireSignup === 'beta') { - return this.promptForSignup({ accountRequiredMessage: $.i18n.t('account.unlock_next_level_with_sign_up') }) + const promptResult = this.promptForSignup({ accountRequiredMessage: $.i18n.t('account.unlock_next_level_with_sign_up') }) + if (promptResult) { + return promptResult + } } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/views/play/CampaignView.js` around lines 1931 - 1936, The current code returns the result of this.promptForSignup(...) inside the block guarding level.allowAnonymous/me.isAnonymous(), which can unintentionally short-circuit level start when promptForSignup is a no-op and returns nothing; instead call this.promptForSignup(...) (await if it is async) without returning its value so execution continues normally — update the conditional that uses level.allowAnonymous, me.isAnonymous(), CAMPAIGN, requireSignup and replace "return this.promptForSignup(...)" with a non-returning invocation (e.g., this.promptForSignup(...); and then continue/return undefined explicitly if needed) to avoid blocking level start.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@app/views/play/CampaignView.js`:
- Around line 1931-1936: The current code returns the result of
this.promptForSignup(...) inside the block guarding
level.allowAnonymous/me.isAnonymous(), which can unintentionally short-circuit
level start when promptForSignup is a no-op and returns nothing; instead call
this.promptForSignup(...) (await if it is async) without returning its value so
execution continues normally — update the conditional that uses
level.allowAnonymous, me.isAnonymous(), CAMPAIGN, requireSignup and replace
"return this.promptForSignup(...)" with a non-returning invocation (e.g.,
this.promptForSignup(...); and then continue/return undefined explicitly if
needed) to avoid blocking level start.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 59cd5387-442c-4b28-ba71-e05b84e5403f
📒 Files selected for processing (4)
app/locale/en.jsapp/schemas/models/campaign.schema.jsapp/views/play/CampaignView.jsapp/views/play/level/modal/HeroVictoryModal.js
✅ Files skipped from review due to trivial changes (1)
- app/locale/en.js
🚧 Files skipped from review as they are similar to previous changes (1)
- app/schemas/models/campaign.schema.js
There was a problem hiding this comment.
🧹 Nitpick comments (1)
app/models/User.js (1)
1485-1495: Missing validation for invalidCAMPAIGNparameter.Unlike
getOrStartRequireSignupExperimentValue, this method doesn't validate thatCAMPAIGNis a key inREQUIRE_SIGN_UP_EXPERIMENT. If called directly with an invalid campaign,REQUIRE_SIGN_UP_EXPERIMENT[CAMPAIGN]will beundefined, which gets passed togetExperimentValueFromQueryandgetExperimentValuepotentially causing unexpected behavior.Consider adding validation or documenting that callers should use
getOrStartRequireSignupExperimentValueinstead.Proposed defensive check
getRequireSignupExperimentValue (CAMPAIGN) { + if (!REQUIRE_SIGN_UP_EXPERIMENT[CAMPAIGN]) { + return null + } if (!me.isAnonymous()) { return 'control' }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/models/User.js` around lines 1485 - 1495, The method getRequireSignupExperimentValue lacks validation of the CAMPAIGN argument against the REQUIRE_SIGN_UP_EXPERIMENT map; add a defensive check at the start of getRequireSignupExperimentValue to verify REQUIRE_SIGN_UP_EXPERIMENT.hasOwnProperty(CAMPAIGN) (or CAMPAIGN in REQUIRE_SIGN_UP_EXPERIMENT) and return null or 'control' (match existing behavior) when invalid, so you don't pass undefined into utils.getExperimentValueFromQuery or me.getExperimentValue; ensure the change references getRequireSignupExperimentValue and REQUIRE_SIGN_UP_EXPERIMENT and keeps existing anonymous-user early-return logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@app/models/User.js`:
- Around line 1485-1495: The method getRequireSignupExperimentValue lacks
validation of the CAMPAIGN argument against the REQUIRE_SIGN_UP_EXPERIMENT map;
add a defensive check at the start of getRequireSignupExperimentValue to verify
REQUIRE_SIGN_UP_EXPERIMENT.hasOwnProperty(CAMPAIGN) (or CAMPAIGN in
REQUIRE_SIGN_UP_EXPERIMENT) and return null or 'control' (match existing
behavior) when invalid, so you don't pass undefined into
utils.getExperimentValueFromQuery or me.getExperimentValue; ensure the change
references getRequireSignupExperimentValue and REQUIRE_SIGN_UP_EXPERIMENT and
keeps existing anonymous-user early-return logic.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c0362250-c038-464f-b546-c87dc4b88019
📒 Files selected for processing (5)
app/models/User.jsapp/schemas/models/campaign.schema.jsapp/schemas/models/level.jsapp/views/play/CampaignView.jsapp/views/play/level/modal/HeroVictoryModal.js
✅ Files skipped from review due to trivial changes (1)
- app/schemas/models/level.js
🚧 Files skipped from review as they are similar to previous changes (2)
- app/schemas/models/campaign.schema.js
- app/views/play/CampaignView.js
see https://github.com/codecombat/codecombat-server/pull/1430 too
db steps:
edit mandate in admin page to add require-sign-up experiment control/beta
edit campaign.levels to add allowAnonymous to true.
Summary by CodeRabbit
New Features
Localization