refactor(core,users): decouple core/users views from optional modules via registries and a users store#4467
Conversation
… via registries + a users store Core layout and the users account view reached directly into optional feature modules (billing, organizations), and users had no store layer: - users.store.js: new Pinia store owning profile update + account delete (mirrors admin/billing/organizations store shape). user.profile.view.vue now calls store actions instead of building axios calls inline. - core.navigation.component.vue: replaced the hard billing nav-gauge import with the useNavExtras() registry seam (mirrors core.footer's useFooterExtras). billing.navExtras.component.vue registers the gauge, reactively gated on meterMode — same v-if behavior, now owned by billing. - user.view.vue: replaced the hard organizations switcher + store import with the useUserHeaderActions() registry seam. organizations.headerAction .component.vue registers the switcher and owns the on-login fetchOrganizations() pre-load (now logged on failure instead of swallowed). Both registrars mount from app.vue, the existing composition root that already wires every optional module. - createComponentRegistry.js: shared register/unregister factory backing both new seams, keeping the bookkeeping in one place. Tests updated/added per touched module, including source-level checks that core/users no longer statically import the optional modules. Closes #4461 Claude-Session: https://claude.ai/code/session_01WfNC8bt1TgL4AsiYgCEGup
… reactive tests app.vue mounted the useNavExtras consumer (devkitNav) before its registrar (billingNavExtras), inverted vs the legalFooterSection→devkitFooter precedent — causes a redundant re-render pass on first mount. Move billingNavExtras above devkitNav so registration happens first (the organizations.headerAction→user.view pair was already correctly ordered: the registrar mounts in app.vue ahead of <router-view>). Add reactive-after-mount tests for both registry seams: flipping meterMode post-mount (billing.navExtras) and isLoggedIn false→true post-mount (organizations.headerAction) — the runtime path the watch()/computed exist for, previously only exercised via immediate-on-mount. Required wrapping the auth-store mock in reactive() (a plain object mock isn't tracked by Vue's reactivity) and tracking+unmounting wrappers in the organizations suite to avoid cross-test watcher leakage once the mock became reactive.
|
Warning Review limit reached
Next review available in: 29 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (17)
✨ Finishing Touches🧪 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 |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #4467 +/- ##
=======================================
Coverage 99.57% 99.57%
=======================================
Files 35 36 +1
Lines 1398 1411 +13
Branches 439 439
=======================================
+ Hits 1392 1405 +13
Misses 6 6 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@coderabbitai full review |
✅ Action performedFull review finished. Your plan includes PR reviews subject to rate limits. More reviews will be available in 29 minutes. |
Summary
core.navigation.component.vue(nav drawer) anduser.view.vue(account header) previously hard-imported optionalbilling/organizationscomponents and stores directly. This introduces a shared component-registry seam (createComponentRegistry+useNavExtras/useUserHeaderActions), mirroring the existinguseFooterExtraspattern:billing/organizationsnow self-register their nav compute-gauge / header org-switcher from invisible registrar components mounted at the app shell composition root (app.vue), andcore/usersjust render whatever is registered — no compile-time dependency on the optional modules. Also addsusers.store.js, since theusersmodule previously had no store anduser.view/user.profile.viewcalled axios directly for profile/delete operations. Behavior is identical; this is a decoupling refactor. Also fixes a mount-order inversion found during pre-PR review:billingNavExtras(the registrar) now mounts abovedevkitNav(the consumer) inapp.vue, matching the workinglegalFooterSection→devkitFooterprecedent, and adds reactive-after-mount test coverage for both registry seams.useFooterExtrasfor the footer, applied to the nav drawer and the account header, plus givingusersa proper store layer instead of view-level axios calls.Scope
core,users,billing,organizations,auth,app,lib/composablesyes—billingandorganizationsnow register into sharedlib/composablesregistries instead of being imported bycore/users;core/usersno longer importbilling/organizationsat alllow— pure refactor, registries are additive, existing UI/behavior parity verified by full unit suite + buildValidation
npm run lintnpm run test:unitnpm run buildbilling.navExtrasmeterMode flip post-mount,organizations.headerActionisLoggedIn flip post-mount)Guardrails check
.env*,secrets/**, keys, tokens)Notes for reviewers
users.store.jswraps existing profile/delete API calls with the same request shape.core.navigation/user.view/app.vuewill need/update-stackto pick up the new registry seam.https://claude.ai/code/session_01WfNC8bt1TgL4AsiYgCEGup