Duplicate Account Manager

Admin login required โ€” same email/password as the Admin Panel.

Duplicate Account Manager

Rule: one mobile number = one account. For each phone number below with 2+ accounts, pick which one to keep (defaults to a genuinely paid/enrolled account over a Free-only one, then whichever has given the most tests) โ€” the others are retired (never hard-deleted: their history stays in Firestore, login is disabled, and any paid access/fees they had are transferred onto the kept account).

Loading duplicate accounts...

Retired accounts still holding a Student ID

A retired (merged-away) account keeps its login email โ€” so it silently holds its old Student ID and can make "Student ID already taken" show up when you edit the real account. This lists every retired account that still holds an ID. Blocking = an active student has that same Student ID but it can't be saved because the retired account has it. "Free Blocking IDs" renames ONLY those retired accounts' login email out of the way (nothing is deleted; history stays). Edit โ†’ Save on the student also frees it automatically now.


Normalize Student IDs to Phone Number

For students who once chose a custom Student ID: makes their Student ID their phone number too, so they can log in with just their phone number + their existing password (no reset needed). Run the duplicate cleanup above FIRST for any phone number this flags as a conflict.


Clear Stale Free/Demo Flags

Fixes two related bugs found 2026-09-12: granting real access (via "Refresh" / duplicate access-fix) never cleared a leftover 3-Day Trial timer (demoExpiresAt) or Free-for-All flag (openAccess) on the same account. Either one alone, even after real access exists, can wrongly sign a student out ("your free demo period has ended") or โ€” for openAccess โ€” actually block real course content at the Firestore security-rules level, not just mis-color the admin panel's name red/gold instead of green. Only accounts with a real enrollment AND at least one leftover flag are affected โ€” a genuine free/demo-only account is left completely untouched.