Skip to content

Register task to assign picture password#14565

Open
ozer550 wants to merge 10 commits intolearningequality:developfrom
ozer550:add-api-support-for-picture-login
Open

Register task to assign picture password#14565
ozer550 wants to merge 10 commits intolearningequality:developfrom
ozer550:add-api-support-for-picture-login

Conversation

@ozer550
Copy link
Copy Markdown
Member

@ozer550 ozer550 commented Apr 9, 2026

Summary

  • Background task to assign picture passwords to learners when picture login is first enabled for a facility.
  • Single API action to save all facility login-related settings (picture login on/off, options, username/password rules) in one place.
  • Response returns updated facility settings, and when a task is started it also returns task info so the app can track it.
  • Frontend uses that action for login settings, keeps other settings on the normal save path.
Screenshot from 2026-04-14 22-37-21

References

closes #14354

Reviewer guidance

  • Add a temporary delay in kolibri/core/auth/tasks.py inside assign_picture_passwords_to_facility so the task runs long enough to visibly show spinners.
  • Log in as a facility admin/superuser in the browser.
  • Navigate to Facility > Settings.
  • switch to Picture password and click Save changes.
  • Confirm UI behavior: save button becomes disabled and spinner appears next to the save button (or bottom bar save, depending on context).
  • Run backend tests for this feature:
    pytest kolibri/core/auth/test/test_api.py
  • Run frontend tests for editor/config flow:
    kolibri/plugins/facility/frontend/composables/__tests__/useFacilityEditor.spec.js

AI usage

AI tools were used to explore and validate approaches for the implementation logic. They also assisted in generating initial versions of the test cases, which were then reviewed and refined to align with the codebase and requirements.

@github-actions github-actions bot added DEV: backend Python, databases, networking, filesystem... APP: Facility Re: Facility App (user/class management, facility settings, csv import/export, etc.) DEV: frontend SIZE: medium labels Apr 9, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

Comment thread kolibri/core/auth/api.py Outdated
@ozer550 ozer550 requested a review from rtibblesbot April 13, 2026 11:48
Copy link
Copy Markdown
Contributor

@rtibblesbot rtibblesbot left a comment

Choose a reason for hiding this comment

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

CI passing. No screenshots in the PR body and the dev server wasn't running locally, so UI was not visually verified — please add screenshots before requesting final review. PR description (summary, references, reviewer guidance, AI usage) is still template placeholder text; AI usage is marked REQUIRED in the template.

  • suggestion × 4: see inline comments
  • praise × 1: see inline comment

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

How was this generated?

Reviewed the pull request diff checking for:

  • Correctness: bugs, edge cases, undocumented behavior, resource leaks, hardcoded values
  • Design: unnecessary complexity, naming, readability, comment accuracy, redundant state
  • Architecture: duplicated concerns, minimal interfaces, composition over inheritance
  • Testing: behavior-based assertions, mocks only at hard boundaries, accurate coverage
  • Completeness: missing dependencies, unupdated usages, i18n, accessibility, security
  • Principles: DRY (same reason to change), SRP, Rule of Three (no premature abstraction)
  • Checked CI status and linked issue acceptance criteria
  • For UI changes: inspected screenshots for layout, visual completeness, and consistency

Comment thread kolibri/core/auth/api.py Outdated
Comment thread kolibri/plugins/facility/frontend/composables/useFacilityEditor.js Outdated
createSnackbar(saveSuccess$());
}
} catch (error) {
createSnackbar(saveFailure$());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion: saveFacilityConfig and saveFacilityLoginSettings each call copySettings() internally. When run in Promise.all, if saveFacilityLoginSettings completes first (calling copySettings() with the pending settings as the new baseline), and saveFacilityConfig then fails, the undoSettingsChange() call here restores settings to the just-copied pending state — effectively a no-op. The user sees the failure snackbar but the UI keeps the unsaved values.

One fix: remove the copySettings() calls from inside both functions and call it once in saveConfig() only after Promise.all resolves successfully.

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.

This might be motivation for moving this task wrangling into the composable, so there's a single save function, but I don't think this is high priority

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Understood — a composable-level single save function is the cleaner fix. Makes sense to defer it.

Comment thread requirements/dev.txt Outdated
if job:
job.update_progress(0, total)

for i, learner in enumerate(learners.iterator(), start=1):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

praise: Using .iterator() here is the right call for large facilities — avoids loading all learner rows into memory at once. The per-user progress updates and the metadata annotation before re-raising NoAvailableSequences make failure diagnosis straightforward.

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.

Feel free to generalize the learner count utility so you can access the queryset for use here too.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Noted — exposing the queryset from the learner count utility would let this code use it directly rather than doing a separate lookup.

@ozer550 ozer550 force-pushed the add-api-support-for-picture-login branch from bc776c9 to b2f369f Compare April 13, 2026 17:44
Copy link
Copy Markdown
Contributor

@rtibblesbot rtibblesbot left a comment

Choose a reason for hiding this comment

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

Prior findings

Resolved:

  • requirements/dev.txt:1 — unrelated setuptools pinning (suggestion) — file removed from PR diff

Unaddressed (re-raised below):

  • api.py:295permission_classes=[IsAuthenticated] override on save_facility_login_settings (suggestion)
  • useFacilityEditor.js:229response.data.id && response.data.status as task discriminant (suggestion)
  • index.vue:492copySettings() race when both Promise.all legs call it (suggestion)
  • PR description and screenshots still placeholder/absent (blocking)

1/5 prior findings resolved. 4 re-raised below.


The rebase commit cleanly delegates exhaustion-checking to are_picture_passwords_exhausted and drops the picture_passwords_exhausted FacilityViewSet annotation — both positive simplifications (inline praise on api.py:318). Still no screenshots and the PR description remains template placeholder text; the prior review's blocking request stands.

blocking:

  • PR description still contains template placeholder text ("WIP…"). Summary, references, reviewer guidance, and AI usage sections are all required before final review.
  • No screenshots added for the Vue/UI changes — visual inspection is not possible without them.

suggestions (re-raised): see inline comments on api.py:295, useFacilityEditor.js:229, index.vue:492

new: see inline comments on api.py:318 (praise), index.vue:159 (suggestion)


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

How was this generated?

Compared the current PR state against findings from a prior review:

  • Retrieved prior bot reviews deterministically via the GitHub API
  • Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
  • Only raised NEW findings for newly introduced code
  • Reviewed the pull request diff checking for correctness, design, architecture, testing, completeness, and adherence to DRY/SRP principles
  • Checked CI status and linked issue acceptance criteria

Comment thread kolibri/core/auth/api.py Outdated
Comment thread kolibri/plugins/facility/frontend/composables/useFacilityEditor.js Outdated
Comment thread kolibri/plugins/facility/frontend/views/FacilityConfigPage/index.vue Outdated
Comment thread kolibri/core/auth/api.py Outdated
class="nested-settings picture-password-assignment-status"
data-testid="picture_password_assignment_status"
>
<KCircularLoader :size="24" />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion: The KCircularLoader is shown without any visible or accessible label while picture passwords are being assigned. Screen-reader users won't get feedback about why the save button is disabled. Consider adding a visually-hidden string (e.g., via $computedClass with a screen-reader-only utility) or an aria-live region announcing the progress state.

Copy link
Copy Markdown
Member

@bjester bjester left a comment

Choose a reason for hiding this comment

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

I'd like to see a test on the permissions handling, and if the permissions handling could be cleaned up.

Out of scope: the existing code that was used as an example for some of this

Comment thread kolibri/core/auth/test/test_api.py Outdated
@patch("kolibri.core.auth.api.get_assigned_sequences", return_value=set())
@patch("kolibri.core.auth.api.PICTURE_PASSWORD_SEQUENCE_COUNT", new=1)
def test_enable_rejected_when_exhausted(self, mock_assigned, mock_task):
mock_assigned.return_value = {"1.2.3"}
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.

nitpick: is this overriding the default return_value=set() in the decorator above?

Comment thread kolibri/plugins/facility/frontend/composables/useFacilityEditor.js Outdated
Comment thread kolibri/core/auth/api.py Outdated
Comment thread kolibri/core/auth/api.py Outdated
Comment thread kolibri/core/auth/api.py
Comment thread kolibri/core/auth/tasks.py Outdated
if job:
job.update_progress(0, total)

for i, learner in enumerate(learners.iterator(), start=1):
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.

Feel free to generalize the learner count utility so you can access the queryset for use here too.

Comment thread kolibri/plugins/facility/frontend/views/FacilityConfigPage/index.vue Outdated
createSnackbar(saveSuccess$());
}
} catch (error) {
createSnackbar(saveFailure$());
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.

This might be motivation for moving this task wrangling into the composable, so there's a single save function, but I don't think this is high priority

Copy link
Copy Markdown
Member

@LianaHarris360 LianaHarris360 left a comment

Choose a reason for hiding this comment

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

The task works as expected, including when the settings are updated. There's a few areas on the frontend that could be improved.

Comment thread kolibri/plugins/facility/frontend/composables/useFacilityEditor.js Outdated
Comment thread kolibri/plugins/facility/frontend/views/FacilityConfigPage/index.vue Outdated
@ozer550 ozer550 requested a review from rtibblesbot April 15, 2026 08:42
Copy link
Copy Markdown
Contributor

@rtibblesbot rtibblesbot left a comment

Choose a reason for hiding this comment

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

Most prior suggestions resolved; two remain unaddressed.

CI passing. UI not verified — no screenshots in the PR and no dev server running locally. Please add screenshots before final review.

Prior findings

2 prior findings unchanged (1 resolved, 1 acknowledged).

Newly resolved:

  • HTTP 202 status check in useFacilityEditor.js (suggestion) ← was UNADDRESSED — response.data.id && response.data.status replaced with response.status === 202 && response.data.task?.id, and backend now nests the dataset and task under their own keys

Still unaddressed (re-raised below):

  • api.py:295permission_classes=[IsAuthenticated] override (suggestion) — no change to this line despite agreement in thread
  • index.vue:159 (prior) → index.vue:204/260KCircularLoader lacks accessible label (suggestion) — loader moved but aria-* attributes still absent

2/4 prior findings resolved or acknowledged. 2 re-raised below.


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

How was this generated?

Compared the current PR state against findings from a prior review:

  • Retrieved prior bot reviews deterministically via the GitHub API
  • Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
  • Only raised NEW findings for newly introduced code
  • Reviewed the pull request diff checking for correctness, design, architecture, testing, completeness, and adherence to DRY/SRP principles
  • Checked CI status and linked issue acceptance criteria

Comment thread kolibri/core/auth/api.py Outdated
methods=["post"],
detail=True,
url_path="save-facility-login-settings",
permission_classes=[IsAuthenticated],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion (re-raised): permission_classes=[IsAuthenticated] still overrides the viewset-level KolibriAuthPermissions. The thread confirmed the fix: drop this override so KolibriAuthPermissions handles authentication and can_update serves as defense-in-depth, matching the pattern used by resetsettings and update_pin. The manual can_update check at line 300 can stay.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I tried removing permission_classes=[IsAuthenticated] and relying only on the viewset-level KolibriAuthPermissions, but that caused valid admin requests to save_facility_login_settings to start returning 403. The reason is that KolibriAuthPermissions.has_object_permission does not treat POST on an existing object as an update path, POST falls through to False.

Copy link
Copy Markdown
Member

@bjester bjester Apr 15, 2026

Choose a reason for hiding this comment

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

So maybe that fact that it's a POST contributes to this? If we're only doing an update, then PATCH seems appropriate.

:disabled="!settingsHaveChanged || pictureLoginTaskLoading"
@click="saveConfig()"
/>
<KCircularLoader
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion (re-raised): KCircularLoader was moved next to the save button, which is an improvement in placement, but it still has no accessible label. While the button is disabled during loading, screen-reader users won't know why or that work is in progress. Consider adding an aria-label to the loader (e.g., aria-label="Assigning picture passwords…") or an aria-live region that announces the loading state when it starts. Same applies to the identical loader in BottomAppBar below (line 260).

const pictureLoginTaskId = ref(null);

async function saveFacilityLoginSettings() {
const data = pick(settings.value, LOGIN_SETTINGS_FIELDS);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

praise: Using pick(settings.value, LOGIN_SETTINGS_FIELDS) here with the constant already used in saveFacilityConfig to exclude the same fields is clean — the field list is defined once and both halves of the split save stay in sync automatically.

@ozer550 ozer550 marked this pull request as ready for review April 15, 2026 09:44
@ozer550 ozer550 changed the title register task to assign picture password Register task to assign picture password Apr 15, 2026
Copy link
Copy Markdown
Contributor

@rtibblesbot rtibblesbot left a comment

Choose a reason for hiding this comment

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

Good progress — the permission override and description gaps are now closed.

CI passing. Screenshot added; spinner placement next to the save button looks correct.

Prior findings

1 prior finding unchanged (1 acknowledged — index.vue copySettings race).

Newly resolved:

  • api.py:295permission_classes=[IsAuthenticated] override (suggestion) ← was UNADDRESSED — override dropped in commit 6bb0079, action changed to PATCH, self.get_object() now delegates auth to the viewset-level KolibriAuthPermissions
  • PR description and screenshots (blocking) ← resolved — summary, references, reviewer guidance, and AI usage are all present; screenshot added

Still unaddressed (re-raised below):

  • index.vue:204/260KCircularLoader lacks accessible label (suggestion) — no aria attributes added, no reply to thread

2/3 prior unresolved findings resolved. 1 re-raised below.


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

How was this generated?

Compared the current PR state against findings from a prior review:

  • Retrieved prior bot reviews deterministically via the GitHub API
  • Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
  • Only raised NEW findings for newly introduced code
  • Reviewed the pull request diff checking for correctness, design, architecture, testing, completeness, and adherence to DRY/SRP principles
  • Checked CI status and linked issue acceptance criteria

Copy link
Copy Markdown
Member

@bjester bjester left a comment

Choose a reason for hiding this comment

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

Code is looking a lot better and I think it's pretty solid. Much of the previous review feedback is resolved. I've tested it and things are working as it should.

Although, I think the styling needs some help. I think it can be simplified a bit, with some styling deduplicated and positioning enhancements. I think rtibblesbot's comment about an announcement is valid, and worth raising if we need a new string or if there's an applicable core string we could use.

Comment thread kolibri/core/auth/test/test_api.py
Comment thread kolibri/core/auth/test/test_api.py Outdated
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

def _setup_task_mocks(self, mock_storage, mock_task):
from kolibri.core.tasks.job import Job
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.

Likely unnecessary inline import?

Comment thread kolibri/plugins/facility/frontend/views/FacilityConfigPage/index.vue Outdated
Comment thread kolibri/plugins/facility/frontend/views/FacilityConfigPage/index.vue Outdated
Comment on lines +260 to +264
<KCircularLoader
v-if="pictureLoginTaskLoading"
:size="24"
data-testid="picture_password_assignment_status"
/>
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.

Since the button is right-aligned, putting the loader to the right of the button causes the button / layout to shift. This is not pleasing to the eye. I suggest moving it to the other side

@bjester
Copy link
Copy Markdown
Member

bjester commented Apr 15, 2026

Also, you have a merge conflict. Tests won't run and we can't be ready to merge this until those conflicts are resolved.

@ozer550 ozer550 force-pushed the add-api-support-for-picture-login branch from 6bb0079 to 6e43f6b Compare April 16, 2026 09:11
Copy link
Copy Markdown
Contributor

@rtibblesbot rtibblesbot left a comment

Choose a reason for hiding this comment

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

Prior findings

All prior findings remain resolved or acknowledged — no changes since last review.

CI still in progress (build assets) at review time; no failures detected. The PR screenshot was taken before the consolidate styling commit — the BottomAppBar now renders the spinner before the button (inverted from what the screenshot shows). Updated screenshots would help confirm the visual state.

  • suggestion: Spinner/button order inconsistency — see inline comment
  • praise: Job import moved to file top; CSS deduplication removes the position: absolute hack and replaces it with normal flow layout

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

How was this generated?

Compared the current PR state against findings from a prior review:

  • Retrieved prior bot reviews deterministically via the GitHub API
  • Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
  • Only raised NEW findings for newly introduced code
  • Reviewed the pull request diff checking for correctness, design, architecture, testing, completeness, and adherence to DRY/SRP principles
  • Checked CI status and linked issue acceptance criteria

/>
class="bottom-bar-save-group"
>
<KCircularLoader
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion: The consolidate styling commit moved the spinner before the button here, so the BottomAppBar now renders <spinner> <button> (spinner on the left). The isAppContext save area (line 193–208) retains <button> <spinner> (button on the left). These two save UIs are now visually inconsistent — one is button-first, the other spinner-first. The PR screenshot (pre-commit) showed button-then-spinner in both. Consider keeping the same order in both: button first, spinner after, to match the isAppContext layout and the existing screenshot.

Copy link
Copy Markdown
Contributor

@rtibblesbot rtibblesbot left a comment

Choose a reason for hiding this comment

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

Prior finding re-raised; new test-only commit looks good.

CI passing.

Screenshot note: the PR screenshot predates the consolidate styling commit. The BottomAppBar currently renders the spinner before the button — opposite to what the screenshot shows. Updated screenshots would confirm the intended visual.

Prior findings

1 prior finding unchanged.

Still unaddressed (re-raised below):

  • index.vue:250 — spinner/button DOM order inconsistency in BottomAppBar (suggestion) — no reply, no code change

0/1 prior findings resolved. 1 re-raised below.


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

How was this generated?

Compared the current PR state against findings from a prior review:

  • Retrieved prior bot reviews deterministically via the GitHub API
  • Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
  • Only raised NEW findings for newly introduced code
  • Reviewed the pull request diff checking for correctness, design, architecture, testing, completeness, and adherence to DRY/SRP principles
  • Checked CI status and linked issue acceptance criteria

/>
class="bottom-bar-save-group"
>
<KCircularLoader
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion (re-raised): In the BottomAppBar the DOM order is <KCircularLoader> then <KButton>, but in the inline isAppContext section (line 194) it's <KButton> then <KCircularLoader>. The flex container renders them in DOM order, so the two contexts show the spinner on opposite sides of the button. Picking one order consistently (button-then-spinner matches the inline section and the existing PR screenshot) would remove the visual discrepancy.

Copy link
Copy Markdown
Member

@LianaHarris360 LianaHarris360 Apr 16, 2026

Choose a reason for hiding this comment

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

Putting the loader on the same side of each button will cause one of the buttons to shift when the loader is displayed, which is not visually pleasing. Disregard this suggestion.

}));
jest.mock('kolibri/composables/useSnackbar');
jest.mock('../../composables/useFacilityEditor');
jest.mock('kolibri-common/composables/useTaskPolling', () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

praise: The useTaskPolling mock shape ({ tasks: ref([]) }) exactly matches the destructuring in setup(), and adding pictureLoginTaskId and saveFacilityLoginSettings to createMockFacilityConfig gives the component everything it needs without over-specifying behavior — clean and minimal.

@ozer550 ozer550 requested a review from bjester April 16, 2026 14:20
@ozer550 ozer550 force-pushed the add-api-support-for-picture-login branch from 6541ce0 to 877dd2d Compare April 16, 2026 17:20
@LianaHarris360
Copy link
Copy Markdown
Member

Reviewer Guidance (scenarios to test):

  1. Start with a facility that has never had picture login enabled and has at least 2 learners
  2. Navigate to the Facility Settings page, select the picture password sign in option, and save the settings.
    • Does a circle loader appear with the save button disabled?
    • Once the loading completes, does a snackbar appear confirming the facility setting change?
  3. After the snackbar appears, refresh the page (note: manually refreshing the page to view the changes is a known bug)
  4. Navigate to the Users page and select "edit details" for one or more learners in the facility
    • Has each learner been assigned a picture password?
  5. Regression testing: Verify that existing facility settings behavior is unaffected
    • Do other facility settings still save and display correctly?
    • Does enabling other sign in options still behave as expected?

Copy link
Copy Markdown
Contributor

@rtibblesbot rtibblesbot left a comment

Choose a reason for hiding this comment

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

1 prior finding unchanged; no new commits.

CI build assets still in progress; no failures detected. Visual: screenshot predates consolidate styling — see inline comment.

Prior findings

1 prior finding unchanged.

Still unaddressed (re-raised below):

  • index.vue:250 — spinner/button DOM order inconsistency in BottomAppBar (suggestion) — no reply, no code change

0/1 prior findings resolved. 1 re-raised below.


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

How was this generated?

Compared the current PR state against findings from a prior review:

  • Retrieved prior bot reviews deterministically via the GitHub API
  • Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
  • Only raised NEW findings for newly introduced code
  • Reviewed the pull request diff checking for correctness, design, architecture, testing, completeness, and adherence to DRY/SRP principles
  • Checked CI status and linked issue acceptance criteria

@pcenov
Copy link
Copy Markdown
Member

pcenov commented Apr 17, 2026

Hi @ozer550 and @LianaHarris360 I confirm that the points in the reviewer guidance are implemented as specified, however while regression testing I noticed that none of the options under 'Users' are working:

users.settings.mp4

@LianaHarris360
Copy link
Copy Markdown
Member

LianaHarris360 commented Apr 17, 2026

@pcenov This seems like a bug that is unrelated to the changes in this PR. It's happening on the develop branch as well, it will be fixed in #14545. Thanks for catching this!

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

Labels

APP: Facility Re: Facility App (user/class management, facility settings, csv import/export, etc.) DEV: backend Python, databases, networking, filesystem... DEV: frontend SIZE: large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add API support for picture login: facility settings toggle and password assignment

6 participants