fix: prevent platform admin from being auto-enrolled in default school

Two root causes fixed:

1. seed_environment.py: KevlarAI website was 'https://kevlarai.com' (real
   domain) instead of 'https://kevlarai.test'. Also, seed step 8 now patches
   kcar's auth user_metadata to set user_type='platform_admin' on every
   reset+seed, so the fix is self-healing and doesn't require manual DB edits.

2. provisioning_service.py: user_type_map now maps 'platform_admin' to
   ('superadmin', 'superadmin'), so _ensure_membership() is never called for
   platform admin accounts and they are never silently enrolled in the
   default institute.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kcar 2026-05-27 04:16:22 +01:00
parent 52532ce00f
commit 035ea17844
2 changed files with 18 additions and 1 deletions

View File

@ -263,6 +263,7 @@ class ProvisioningService:
"admin": ("superadmin", "superadmin"), "admin": ("superadmin", "superadmin"),
"super_admin": ("superadmin", "superadmin"), "super_admin": ("superadmin", "superadmin"),
"superadmin": ("superadmin", "superadmin"), "superadmin": ("superadmin", "superadmin"),
"platform_admin": ("superadmin", "superadmin"),
} }
neo_user_type, worker_type = user_type_map.get(user_type_raw, (user_type_raw or "standard", user_type_raw or "standard")) neo_user_type, worker_type = user_type_map.get(user_type_raw, (user_type_raw or "standard", user_type_raw or "standard"))

View File

@ -203,7 +203,7 @@ def seed() -> Dict[str, Any]:
"name": KEVLARAI_NAME, "name": KEVLARAI_NAME,
"urn": KEVLARAI_URN, "urn": KEVLARAI_URN,
"status": "active", "status": "active",
"website": "https://kevlarai.com", "website": "https://kevlarai.test",
"address": {"line1": "1 AI Lane", "city": "London", "postcode": "EC1A 1BB"}, "address": {"line1": "1 AI Lane", "city": "London", "postcode": "EC1A 1BB"},
"metadata": {"headteacher": "Alex Admin", "seeded": True}, "metadata": {"headteacher": "Alex Admin", "seeded": True},
}, on_conflict="id") }, on_conflict="id")
@ -392,6 +392,22 @@ def seed() -> Dict[str, Any]:
errors.append(f"kcar_admin: {e}") errors.append(f"kcar_admin: {e}")
logger.error(f" {e}") logger.error(f" {e}")
# Fix kcar's auth user_metadata so user_type is "platform_admin", not "teacher".
# Without this, POST /user/init assigns kcar to the default school on first login.
try:
r = requests.patch(
f"{url}/auth/v1/admin/users/{KCAR_ID}",
headers=headers,
json={"user_metadata": {"user_type": "platform_admin"}},
)
if r.status_code in (200, 201):
logger.info(" kcar → user_type: platform_admin ✓")
else:
logger.warning(f" kcar user_metadata patch failed ({r.status_code}): {r.text[:120]}")
except Exception as e:
errors.append(f"kcar_user_type: {e}")
logger.error(f" {e}")
# ── Summary ─────────────────────────────────────────────────────────────── # ── Summary ───────────────────────────────────────────────────────────────
results["success"] = len(errors) == 0 results["success"] = len(errors) == 0
results["errors"] = errors results["errors"] = errors