t4: consolidate seed scripts, remove demo modes, standardize passwords
api-ci-deploy / test-build-deploy (push) Has been cancelled

This commit is contained in:
2026-05-29 19:51:32 +01:00
parent abc90fa1b6
commit e66c8ec291
10 changed files with 192 additions and 995 deletions
+26 -17
View File
@@ -20,14 +20,17 @@ import time
import requests
from typing import Dict, Any, Optional, List
SUPA_URL = os.environ["SUPABASE_URL"]
SERVICE_KEY = os.environ["SERVICE_ROLE_KEY"]
API_BASE = os.environ.get("API_BASE_URL", "http://localhost:8000")
from run.initialization.seed_environment import get_seed_password
GREENFIELD_ADMIN_EMAIL = "[email protected]"
GREENFIELD_ADMIN_PWD = "Admin@Cc2025!"
PWD_TEACHER = "Teacher@Cc2025!"
PWD_STUDENT = "Student@Cc2025!"
def _runtime_context() -> Dict[str, str]:
return {
"supa_url": os.environ["SUPABASE_URL"],
"service_key": os.environ["SERVICE_ROLE_KEY"],
"api_base": os.environ.get("API_BASE_URL", "http://localhost:8000"),
}
# ─── Period templates ──────────────────────────────────────────────────────────
@@ -145,18 +148,20 @@ STUDENT_ENROLLMENTS = {
# ─── Helpers ───────────────────────────────────────────────────────────────────
def _sb_headers() -> Dict:
service_key = _runtime_context()["service_key"]
return {
"apikey": SERVICE_KEY,
"Authorization": f"Bearer {SERVICE_KEY}",
"apikey": service_key,
"Authorization": f"Bearer {service_key}",
"Content-Type": "application/json",
"Prefer": "return=representation",
}
def _sign_in(email: str, password: str) -> str:
ctx = _runtime_context()
r = requests.post(
f"{SUPA_URL}/auth/v1/token?grant_type=password",
headers={"apikey": SERVICE_KEY, "Content-Type": "application/json"},
f"{ctx['supa_url']}/auth/v1/token?grant_type=password",
headers={"apikey": ctx["service_key"], "Content-Type": "application/json"},
json={"email": email, "password": password},
)
r.raise_for_status()
@@ -164,8 +169,9 @@ def _sign_in(email: str, password: str) -> str:
def _api(token: str, method: str, path: str, body: Dict = None) -> Dict:
api_base = _runtime_context()["api_base"]
h = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
r = getattr(requests, method)(f"{API_BASE}{path}", headers=h, json=body)
r = getattr(requests, method)(f"{api_base}{path}", headers=h, json=body)
try:
return r.json()
except Exception:
@@ -174,8 +180,9 @@ def _api(token: str, method: str, path: str, body: Dict = None) -> Dict:
def _get_profile_id(email: str) -> Optional[str]:
"""Look up a profile's UUID by email via Supabase service role."""
supa_url = _runtime_context()["supa_url"]
r = requests.get(
f"{SUPA_URL}/rest/v1/profiles",
f"{supa_url}/rest/v1/profiles",
headers=_sb_headers(),
params={"email": f"eq.{email}", "select": "id", "limit": "1"},
)
@@ -185,8 +192,9 @@ def _get_profile_id(email: str) -> Optional[str]:
def _get_teacher_timetable_id(profile_id: str) -> Optional[str]:
"""Return the Supabase teacher_timetables.id for a given profile."""
supa_url = _runtime_context()["supa_url"]
r = requests.get(
f"{SUPA_URL}/rest/v1/teacher_timetables",
f"{supa_url}/rest/v1/teacher_timetables",
headers=_sb_headers(),
params={"profile_id": f"eq.{profile_id}", "select": "id", "limit": "1"},
)
@@ -196,10 +204,11 @@ def _get_teacher_timetable_id(profile_id: str) -> Optional[str]:
def _patch_slot_class_ids(teacher_tt_sb_id: str, class_code_to_id: Dict[str, str]) -> int:
"""Update class_id FK on teacher_timetable_slots rows via Supabase service role."""
supa_url = _runtime_context()["supa_url"]
patched = 0
for code, class_uuid in class_code_to_id.items():
r = requests.patch(
f"{SUPA_URL}/rest/v1/teacher_timetable_slots",
f"{supa_url}/rest/v1/teacher_timetable_slots",
headers=_sb_headers(),
params={
"teacher_timetable_id": f"eq.{teacher_tt_sb_id}",
@@ -224,7 +233,7 @@ def seed() -> Dict[str, Any]:
# ── [1] Sign in as Greenfield admin ───────────────────────────────────────
print("\n[1] Signing in as [email protected]...")
try:
admin_token = _sign_in(GREENFIELD_ADMIN_EMAIL, GREENFIELD_ADMIN_PWD)
admin_token = _sign_in(GREENFIELD_ADMIN_EMAIL, get_seed_password("school_admin"))
print(" ✓ signed in")
except Exception as e:
return {"success": False, "error": str(e)}
@@ -331,7 +340,7 @@ def seed() -> Dict[str, Any]:
for teacher_email, slot_tuples in TEACHER_SLOTS.items():
try:
teacher_token = _sign_in(teacher_email, PWD_TEACHER)
teacher_token = _sign_in(teacher_email, get_seed_password("teacher"))
except Exception as e:
err = f"login {teacher_email}: {e}"
print(f"{err}")
@@ -439,7 +448,7 @@ def seed() -> Dict[str, Any]:
results["materialize"] = {}
for teacher_email in TEACHER_SLOTS:
try:
teacher_token = _sign_in(teacher_email, PWD_TEACHER)
teacher_token = _sign_in(teacher_email, get_seed_password("teacher"))
except Exception as e:
err = f"login {teacher_email}: {e}"
print(f"{err}")