Skip to content

feat(instructor): accept a National ID in batch enrollment (existing accounts) - #102

Merged
AliAlfaifi merged 2 commits into
fix/batch-enroll-strip-invisible-charsfrom
feat/batch-enroll-national-id
Oct 6, 2026
Merged

AliAlfaifi merged 2 commits into
fix/batch-enroll-strip-invisible-charsfrom
feat/batch-enroll-national-id

Conversation

@AliAlfaifi

Copy link
Copy Markdown

What

Course teams can type a National ID in the instructor dashboard's batch-enrollment box (Membership tab), mixed with emails and usernames. Existing accounts only.

  • A line that is 10 digits starting with 1 or 2 (after invisible-char stripping and Arabic-Indic → ASCII digits) is looked up only in custom_reg_form.ExtraInfo.national_id (normalized form and as typed).
  • Found → the linked account is processed exactly as if its username had been typed: enroll/unenroll, audit row, events, and the notify email goes to that account's own email.
  • Not found → the line fails: "No account found with this National ID". No invite, no email, no fallback to a username with the same digits (owner decision).
  • Ambiguous (the ID belongs to one account and is another account's username, or matches two rows) → the line fails; nothing enrolled.
  • Results show the full ID as typed plus the resolved username and email; the async results CSV gains resolved_email / resolved_username columns. Server logs mask the ID to its last 4 digits.
  • Scope: the dashboard POST only (allow_national_id, sync and async). The /bulk_enroll REST API and other callers keep stock behaviour. If custom_reg_form is not installed, ID-shaped lines fall through to the stock lookup.
  • Membership help text gains one new translatable sentence (needs an Arabic string in futurex-translations).

Prod impact (read-replica, 2026-10-06)

41,859 accounts have a 10-digit username; 39,478 of them have it equal to their National ID (unchanged behaviour). 1,937 have a 10-digit username and no ID on file: typing that number now fails, so teams use their email. 444 have an ID that differs from their username.

Tests

Container run: instructor test_utils.py, test_api.py, test_enrollment.py, instructor_task/tests, bulk_enroll, ccx → 581 passed, 9 skipped (existing CCX perf). Every precedence row, normalization, Arabic digits, unenroll, the app-missing fall-through, a mixed batch, the async worker end to end, and a view test with RLM/BOM-wrapped IDs. Repo pylint: clean on all 8 touched files. Not run: Jasmine / browser rendering.

Merge order

Base is #101 branch — merge that first; GitHub retargets this PR to open-release/teak.nelp. Teak-only divergence (# NELC:): the Mako instructor dashboard is replaced in Verawood.

🤖 Generated with Claude Code

AliAlfaifi and others added 2 commits October 6, 2026 23:11
…xisting accounts only)

Course teams can type a National ID, mixed with emails/usernames, in the
Membership tab batch enrollment box. An ID-shaped line ([12] + 9 digits after
Arabic-Indic normalisation) is looked up in custom_reg_form.ExtraInfo.national_id
and then processed exactly as if the matching account's username/email had been
typed: enroll/unenroll, ManualEnrollmentAudit, events, and the notification goes
to that account's own email. Sync and async share process_single_student_enrollment.

- An ID with no account fails that line ("No account found with this National
  ID"); no CourseEnrollmentAllowed, no email, no fallback.
- An ID-shaped line is only ever a National ID: one that matches no account
  fails as "No account found with this National ID" even when a username equals
  the digits (a typo must not enrol that user); nothing is enrolled, no email.
  ID and username of the SAME account is fine; the ID of one account that is also
  the username of another (or an ID matching two rows) fails as ambiguous.
- Core does not import eox_nelp or custom_reg_form: the model is fetched with
  apps.get_model, and without the app the stock lookup runs unchanged.
- Resolution is opt-in per call (allow_national_id), set only by the dashboard
  POST (sync and async task_input); the bulk_enroll REST API keeps its contract.
- Results/CSV carry resolved_email/resolved_username; membership.js shows them;
  a typed ID is masked in server logs; help text added as a separate string so
  existing translations stay valid.

Divergences are marked `# NELC:` for the next upgrade re-port.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…slint

' <' + email + '>' is read by xsslint as HTML concatenation
(javascript-concat-html over threshold). The text is rendered with
.text(), so this is cosmetic; parentheses keep the output readable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@AliAlfaifi
AliAlfaifi merged commit aaf6d59 into fix/batch-enroll-strip-invisible-chars Oct 6, 2026
47 checks passed
@AliAlfaifi
AliAlfaifi deployed to fix/batch-enroll-strip-invisible-chars October 6, 2026 21:08 — with GitHub Actions Active
@AliAlfaifi
AliAlfaifi had a problem deploying to fix/batch-enroll-strip-invisible-chars October 6, 2026 21:08 — with GitHub Actions Failure
@AliAlfaifi

Copy link
Copy Markdown
Author

Merged into the stacked base branch, not open-release/teak.nelp — the National ID code did not reach teak.nelp. Re-opened as #103 against teak.nelp.

@AliAlfaifi
AliAlfaifi deployed to open-release/teak.nelp October 6, 2026 21:55 — with GitHub Actions Active
@AliAlfaifi
AliAlfaifi deployed to open-release/teak.nelp October 6, 2026 21:55 — with GitHub Actions Active

This branch had an error being deployed

1 failed and 1 active deployments
open-release/teak.nelp — 8169519f Deployed Oct 6, 2026 by AliAlfaifi via create-jira-issue / create_jira_issue #41
fix/batch-enroll-strip-invisible-chars — 8169519f Deployed Oct 6, 2026 by AliAlfaifi via create-jira-issue / create_jira_issue #40
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.

1 participant