Skip to content

Migrate user_profile to the new resource-layer methods - #15183

Open
rtibblesbot wants to merge 5 commits into
learningequality:developfrom
rtibblesbot:issue-15064-fba872
Open

Migrate user_profile to the new resource-layer methods#15183
rtibblesbot wants to merge 5 commits into
learningequality:developfrom
rtibblesbot:issue-15064-fba872

Conversation

@rtibblesbot

@rtibblesbot rtibblesbot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

References

Reviewer guidance

Code review

For a developer reading the diff.

  • SelectFacility.vue:125NetworkLocationResource is shared outside this plugin, so the recipe's shared-_v2 branch applies: the call site moves, the legacy standalone stays for the static/dynamic resources.
  • actions.js:13update gets no baseline; ProfileEditPage.getUpdates() (:181) already diffs against the loaded user. The save is still a single-field PATCH /api/auth/facilityuser/<id>/.
  • ProfilePage.spec.js:31 — the module automock is dropped: it stubs useRetrieve too, so the spec spies on the real retrieve.
  • Reads that omitted force (useCurrentUser, ProfileEditPage.vue:173) now always hit the network, and a MergeFacility poll tick coalesces onto an in-flight GET rather than queueing behind it.
  • useCurrentUser no longer leaves isLoading true after a failed fetch. clear_v2 resolves response.data, which all three call sites discard.
  • The merge task's completion path (retrieve, clear_v2) needs one user on two devices, so MergeFacility.spec.js is its only cover.
  • /profile/#/edit reports one KDS KSelect placeholder-contrast axe AA violation, present on develop too; no markup or style line is in this diff.

QA steps

For a tester installing the build artifacts in a VM. No UI change — every screen below should behave as on develop. Rows 3 and 6 need a second user in the facility; rows 5 and 6 need a second VM on the network running any released Kolibri.

Where What to check
Profile, signed in as a learner full name, username, facility and role all show, and a reload shows the same values
Profile > Edit — change full name, username, birth year, gender, save snackbar shows, page returns to Profile, new values on both the profile and the reopened edit form
Profile > Edit — save with the second user's username, then with a blank full name each error lands on its own field and focus moves there; a corrected resubmit saves
Profile > Change password — enter the old and the new password modal closes, and signing out and back in with the new password works
Profile > Change facility — device list the second VM is found, each device lists its facilities, no facility appears twice, and a device you then power off is dropped rather than wedging the modal
Profile > Change facility — confirmation screen, run once as the only user in the source facility and once with a second user in it the "last user on this device" wording and the merge-or-new-account choice differ between the runs
Page Screenshot
Profile, after a full-name save Profile
Change facility, device list Select facility

AI usage

Claude Code applied the shared migration recipe and rewrote the two specs whose mocks named the replaced methods. Verified with Jest, prek, and manual QA in a browser against a local server.

@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?
  • Ran pre-flight CI checks (lint, format, tests) and verified all pass
  • Rebased onto the target branch and resolved any conflicts
  • Reorganized commit history into clean, logical commits
  • Audited the diff to ensure only issue-relevant files are changed
  • Built PR body from the repository's PR template with evidence blocks

@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?
  • Ran pre-flight CI checks (lint, format, tests) and verified all pass
  • Rebased onto the target branch and resolved any conflicts
  • Reorganized commit history into clean, logical commits
  • Audited the diff to ensure only issue-relevant files are changed
  • Built PR body from the repository's PR template with evidence blocks
@rtibblesbot

🟡 Waiting for feedback

Last updated: 2026-08-25 00:29 UTC

@github-actions github-actions Bot added APP: User Re: User app (sign-in, sign-up, user profile, etc.) DEV: frontend SIZE: medium labels Aug 12, 2026
@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

@rtibblesbot
rtibblesbot marked this pull request as ready for review August 12, 2026 18:34
@rtibblesbot

rtibblesbot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

Build EXE file failed on the chocolatey community feed, not the diff: choco install wget got Failed to fetch results from V2 feedUnable to find package 'Wget', so make webview2 then died on wget: command not found. #15184 hit the same feed error on innosetup 45 minutes later and went green on its next push. The feed answers 200 again; the job needs a re-run, which this account has no rights for.

@rtibblesbot

Copy link
Copy Markdown
Contributor Author

Resolved without intervention: a fresh run on the same SHA (31629087140) built the EXE green. No re-run needed.

@rtibblesbot

Copy link
Copy Markdown
Contributor Author

Added a QA steps section to the body — same request as on #15182, applied across the family's open PRs.

@AlexVelezLl AlexVelezLl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just couple of small details :).

Comment on lines 53 to 63
/**
* @name fetchModel
* @function
* @returns {NetworkLocation}
*/

/**
* @name fetchCollection
* @function
* @returns {NetworkLocation[]}
*/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Lets also remove these comments, please.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Gone — all six. grep -rn "@name fetch\(Model\|Collection\)" over kolibri/ and packages/ matches only this file: two stubs in each of the three resources. Same deletion as #15163's hunk.

Comment on lines 28 to 46
function updateConnectionStatus(id) {
const url = urls['kolibri:core:networklocation_update_connection_status'](id);
return this.client({ url, method: 'post' }).then(response => {
return response.data;
});
}

/**
* Fetch the facilities advertised by a remote network location.
* @param {string} id - network location id
* @returns {{facilities: [{id: string}]}} the facilities listing from the remote device
*/
function fetchFacilities(id) {
return this.client({
url: urls['kolibri:core:networklocation_facilities_detail'](id),
}).then(response => {
return response.data;
});
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could we turn this into the NetworkLocationResource object and use this.request instead?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — fetchFacilities is now a NetworkLocationResource method over this.request; the standalone and the _v2 sibling I had added are both gone.

  • The standalone resolved networklocation_facilities_detail for all three resources, so the static and dynamic registrations pointed at the networklocation endpoint regardless. request cannot do that, and nothing called them — dropped.
  • grep -rn "NetworkLocationResource\.fetchFacilities": one caller, SelectDeviceModalGroup/api.js:46, on NetworkLocationResource and unchanged. SelectFacility.vue:125 is back to fetchFacilities, so that file no longer differs from develop.
  • updateConnectionStatus is the same shape in this file, but it is Migrate kolibri-common to the new resource methods #15163's to rewrite — left alone so two branches do not both move it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Landed in develop via #15163 while this sat — fetchFacilities_v2 and updateConnectionStatus_v2 on NetworkLocationResource over this.request, and the @name stubs gone. That covers this thread and the two siblings on this file.

The rebase takes develop's copy whole, so NetworkLocationResource.js is out of this PR's diff; user_profile now calls fetchFacilities_v2 at SelectFacility.vue:125.

Comment thread kolibri/plugins/user_profile/frontend/modules/profile/actions.js
@rtibblesbot

Copy link
Copy Markdown
Contributor Author

Red again on ac943425f, same chocolatey outage as 12 Aug, not self-resolved this time: choco install wget got a 503 from the community V2 feed, exited 0 with Chocolatey installed 0/0 packages, and make webview2 then died on wget: command not found (job). The feed answers 200 now; Build EXE file needs a re-run, which this account cannot trigger. Every other check on this SHA is green, including Frontend tests and All file linting.

Comment on lines 28 to 33
@@ -32,69 +32,27 @@ function updateConnectionStatus(id) {
});
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we move this one, too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — updateConnectionStatus is now a NetworkLocationResource method over this.request({ method: 'POST', action: 'update_connection_status', routeParams: id }), same URL and verb as the hardcoded urls[...] call. Its only caller (SelectDeviceModalGroup/api.js:75) is unchanged.

Swept the branch for the same class — legacy this.client({ url: urls[...] }) custom methods on any resource this PR touches: one file matched (git diff --name-only upstream/develop...HEAD | xargs grep -l "this.client("), and it had exactly this one function left. urls is now an unused import there and is dropped.

Static/dynamic registrations dropped too: grep -rn "StaticNetworkLocationResource\|DynamicNetworkLocationResource" shows only create/delete calls in api.js, so neither updateConnectionStatus was ever called.

No spec here for the same reason as fetchFacilities#15163 adds NetworkLocationResource.spec.js covering both, and a partial copy would be an add/add conflict. Verified locally with a throwaway spec: URL .../networklocation_update_connection_status/dev-1, method POST, resolves response.data.

@rtibblesbot
rtibblesbot force-pushed the issue-15064-fba872 branch 2 times, most recently from f9aea87 to 2c14075 Compare August 17, 2026 21:58
@radinamatic

Copy link
Copy Markdown
Member

Removed the Needs QA label so the PR can be rebased to include changes from #15217 that will unblock the pending QA workflows.

@rtibblesbot

Copy link
Copy Markdown
Contributor Author

Rebased onto develop at eca38c5, which contains #15217. All five commits replayed without conflict — #15217 is backend-only (kolibri/core/auth, discovery, serializers.py), and this branch touches no Python.

Re-verified after the rebase: pnpm test-jest --testPathPatterns user_profile 73 passed / 11 suites; SelectDevice|NetworkLocation|SyncSchedule (the callers of the two methods moved onto NetworkLocationResource) 335 passed / 3 suites; prek run --from-ref upstream/develop --to-ref HEAD clean.

Also re-swept the AC over the 141 new develop commits, in case one had landed a legacy call in this plugin: grep -rnE "fetchModel|fetchCollection|saveModel|deleteModel|saveCollection|deleteCollection|clearCache|getModel|getCollection|addModel" across kolibri/plugins/user_profile/ — no matches. Ready for QA.

@rtibblesbot

Copy link
Copy Markdown
Contributor Author

Holding off on changes while this PR is in 🧪 Needs QA — the branch will not move while it is being tested. Questions still get answered.

Change the board status when QA is done and I'll pick up any outstanding review feedback, CI failures and conflicts on the next cycle.


@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?
  • Ran pre-flight CI checks (lint, format, tests) and verified all pass
  • Rebased onto the target branch and resolved any conflicts
  • Reorganized commit history into clean, logical commits
  • Audited the diff to ensure only issue-relevant files are changed
  • Built PR body from the repository's PR template with evidence blocks

@AlexVelezLl

Copy link
Copy Markdown
Member

Hey @rtibblesbot! Please rebase.

rtibblesbot and others added 5 commits August 24, 2026 12:50
`fetchFacilities_v2` landed on `NetworkLocationResource` with learningequality#15163. The legacy
standalone stays in place: the resource is shared outside this plugin, so learningequality#15057
moves the call site only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The read and the writes move together: `fetchModel` is what marked the model
synced, which is what made `saveModel(..., { exists: true })` PATCH a diff
rather than the whole cached object.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`force: true` has no successor — the cache it bypassed is gone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The spec factory drops `clear` rather than keeping it, so a missed call site
throws instead of passing silently.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@rtibblesbot

Copy link
Copy Markdown
Contributor Author

Rebased onto develop at a703bd9 — one conflict, in NetworkLocationResource.js.

#15163 merged there in the meantime with the same this.request bodies you asked for, as fetchFacilities_v2 / updateConnectionStatus_v2, and with the @name stubs dropped — all three of your requests on that file. Took develop's copy whole: renaming _v2 away now would break SelectDeviceModalGroup/api.js and NetworkLocationResource.spec.js, which #15163 points at those names. The first commit is now just SelectFacility.vue:125 moving to fetchFacilities_v2, and the diff is entirely inside user_profile.

Re-swept the plugin for the class afterwards — grep -rnE "fetchModel|fetchCollection|saveModel|deleteModel|saveCollection|deleteCollection|clearCache|getModel|getCollection|addModel|force: true" over kolibri/plugins/user_profile/ matches nothing. All 13 remaining resource calls are new-layer: startTask already delegates to this.create, and ProfilePage/index.vue:336 is useFacility()'s fetchFacilities, not a resource method.

pnpm test-jest --testPathPatterns user_profile: 11 suites / 73 tests, unchanged from before the rebase. NetworkLocationResource + SelectDevice specs green. prek run --from-ref upstream/develop --to-ref HEAD passes.

@radinamatic

Copy link
Copy Markdown
Member

@rtibblesbot Once this is ready for the manual testing (labeled Needs QA, could you please separate clearly the QA guidelines for code review (if necessary) from the instructions for manual QA? As of now they seem to be mixed... 🤔

@rtibblesbot

Copy link
Copy Markdown
Contributor Author

Split, @radinamaticReviewer guidance now has ### Code review and ### QA steps.

What moved out of the QA half: the GET/PATCH endpoint and payload assertions, the spec/automock notes and the behaviour deltas, all now under code review. The QA half assumes the build artifacts installed in a VM, so the "register localhost as its own peer" rig became a second VM on the network. All six flows kept, as a Where | What to check table — bullets did not fit the body budget.

Swept my other five open PRs for the same mix: four matched, three needed the fix.

PR State
#15182, #15206 same unlabelled code-review bullets above a ### QA steps block — split. #15206's two pingback rows need a seeded PingbackNotification, so they moved to the code-review half rather than staying as a step QA cannot run
#15219 its walkthrough asked for "zero rows in content_channelmetadata" — reworded to on-screen terms under ### QA steps
#15207 already split
#15028, #14903 backend-only, no QA half to separate

@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

APP: User Re: User app (sign-in, sign-up, user profile, etc.) DEV: frontend SIZE: small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate user_profile to the new Resource-layer methods

3 participants