docs(reset): clarify exam-corpus scope
Some checks failed
api-ci-deploy / test-build-deploy (push) Has been cancelled
Some checks failed
api-ci-deploy / test-build-deploy (push) Has been cancelled
This commit is contained in:
parent
25d02aedeb
commit
5da108df13
@ -132,9 +132,13 @@ async def reset_environment(
|
|||||||
"""DESTRUCTIVE: wipe test data. Platform admin only.
|
"""DESTRUCTIVE: wipe test data. Platform admin only.
|
||||||
|
|
||||||
scope (query param):
|
scope (query param):
|
||||||
- all : full wipe (Neo4j + Supabase data + auth users) AND exam subsystem + storage.
|
- all : full wipe (Neo4j + Supabase data + auth users) AND the entire
|
||||||
- exam-corpus : ONLY the exam corpus — eb_*/exam_* tables + cc.examboards storage objects
|
exam-marker subsystem below.
|
||||||
(load/unload the public corpus without touching schools/users).
|
- exam-corpus : ONLY the entire exam-marker subsystem, not just public papers:
|
||||||
|
public corpus/eb_* data, cc.examboards storage objects, exam
|
||||||
|
templates, template layouts, questions, boundaries, response
|
||||||
|
areas, marking batches, student submissions, and mark entries
|
||||||
|
(without touching schools/users).
|
||||||
- timetable : ONLY timetable/calendar materialization tables.
|
- timetable : ONLY timetable/calendar materialization tables.
|
||||||
"""
|
"""
|
||||||
if scope not in ("all", "exam-corpus", "timetable"):
|
if scope not in ("all", "exam-corpus", "timetable"):
|
||||||
|
|||||||
@ -82,8 +82,11 @@ SUPABASE_TABLES_TO_CLEAR = [
|
|||||||
"admin_profiles",
|
"admin_profiles",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Exam subsystem tables, FK child-first. NOT in the list above — the previous full reset()
|
# Exam-marker subsystem tables, FK child-first. scope="exam-corpus" is deliberately
|
||||||
# never cleared exam data or storage at all; the granular scopes below fold it in.
|
# broader than "public papers": it wipes public corpus eb_* rows, templates, layouts,
|
||||||
|
# questions, boundaries, response areas, marking batches, student submissions, and mark
|
||||||
|
# entries. NOT in the list above — the previous full reset() never cleared exam data
|
||||||
|
# or storage at all; the granular scopes below fold it in.
|
||||||
EXAM_CORPUS_TABLES = [
|
EXAM_CORPUS_TABLES = [
|
||||||
"mark_entries",
|
"mark_entries",
|
||||||
"student_submissions",
|
"student_submissions",
|
||||||
@ -114,7 +117,8 @@ TIMETABLE_TABLES = [
|
|||||||
"planned_lessons",
|
"planned_lessons",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Buckets whose objects the exam-corpus reset clears (Storage API — protect_delete blocks raw SQL).
|
# Bucket whose objects scope="exam-corpus" clears for the whole exam-marker subsystem
|
||||||
|
# (Storage API — protect_delete blocks raw SQL).
|
||||||
EXAM_STORAGE_BUCKET = "cc.examboards"
|
EXAM_STORAGE_BUCKET = "cc.examboards"
|
||||||
|
|
||||||
|
|
||||||
@ -217,8 +221,13 @@ def _clear_tables(url: str, headers: dict, tables: List[str]) -> "tuple[List[str
|
|||||||
|
|
||||||
|
|
||||||
def _clear_exam_storage() -> Dict[str, Any]:
|
def _clear_exam_storage() -> Dict[str, Any]:
|
||||||
"""Remove cc.examboards objects via the Storage API (protect_delete blocks raw SQL deletes).
|
"""Remove cc.examboards objects for the exam-marker subsystem.
|
||||||
Gathers storage_loc from eb_exams/eb_specifications BEFORE the rows are cleared."""
|
|
||||||
|
scope="exam-corpus" is not limited to public-paper metadata: it also removes the
|
||||||
|
storage objects that back exam board corpus files and any downstream exam-marker
|
||||||
|
artifacts referenced from eb_exams/eb_specifications. Gathers storage_loc from
|
||||||
|
eb_exams/eb_specifications BEFORE the rows are cleared.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
from modules.database.supabase.utils.client import SupabaseServiceRoleClient
|
from modules.database.supabase.utils.client import SupabaseServiceRoleClient
|
||||||
from modules.database.supabase.utils.storage import StorageAdmin
|
from modules.database.supabase.utils.storage import StorageAdmin
|
||||||
@ -257,8 +266,12 @@ def _clear_exam_storage() -> Dict[str, Any]:
|
|||||||
def reset(scope: str = "all") -> Dict[str, Any]:
|
def reset(scope: str = "all") -> Dict[str, Any]:
|
||||||
"""Destructive reset. scope ∈ {all, exam-corpus, timetable}.
|
"""Destructive reset. scope ∈ {all, exam-corpus, timetable}.
|
||||||
|
|
||||||
- all : full wipe (Neo4j + Supabase data + auth users) AND the exam subsystem + storage.
|
- all : full wipe (Neo4j + Supabase data + auth users) AND the entire
|
||||||
- exam-corpus : ONLY eb_*/exam_* tables + cc.examboards storage objects (load/unload the corpus).
|
exam-marker subsystem listed below.
|
||||||
|
- exam-corpus : ONLY the entire exam-marker subsystem, not just public papers:
|
||||||
|
public corpus/eb_* data, cc.examboards storage objects, exam
|
||||||
|
templates, template layouts, questions, boundaries, response
|
||||||
|
areas, marking batches, student submissions, and mark entries.
|
||||||
- timetable : ONLY timetable/calendar materialization tables.
|
- timetable : ONLY timetable/calendar materialization tables.
|
||||||
"""
|
"""
|
||||||
scope = (scope or "all").lower()
|
scope = (scope or "all").lower()
|
||||||
@ -268,7 +281,7 @@ def reset(scope: str = "all") -> Dict[str, Any]:
|
|||||||
_assert_reset_allowed(url, scope)
|
_assert_reset_allowed(url, scope)
|
||||||
|
|
||||||
if scope == "exam-corpus":
|
if scope == "exam-corpus":
|
||||||
logger.info("RESET (scope=exam-corpus) — exam tables + cc.examboards storage")
|
logger.info("RESET (scope=exam-corpus) — entire exam-marker subsystem: public corpus/eb_* data, cc.examboards storage, templates/layout/questions/boundaries/response areas, marking batches, submissions, mark entries")
|
||||||
storage = _clear_exam_storage()
|
storage = _clear_exam_storage()
|
||||||
cleared, failed = _clear_tables(url, headers, EXAM_CORPUS_TABLES)
|
cleared, failed = _clear_tables(url, headers, EXAM_CORPUS_TABLES)
|
||||||
return {"scope": scope, "exam_storage": storage, "tables_cleared": cleared, "tables_failed": failed}
|
return {"scope": scope, "exam_storage": storage, "tables_cleared": cleared, "tables_failed": failed}
|
||||||
@ -342,9 +355,12 @@ def reset(scope: str = "all") -> Dict[str, Any]:
|
|||||||
)
|
)
|
||||||
logger.info(" kcar → admin_profiles restored ✓")
|
logger.info(" kcar → admin_profiles restored ✓")
|
||||||
|
|
||||||
# ── 5. Exam subsystem: storage objects (Storage API) + exam tables ───────────
|
# ── 5. Exam-marker subsystem: storage objects (Storage API) + all exam tables ──
|
||||||
# (The legacy full reset cleared neither exam tables nor storage — folded in here.)
|
# This is the same destructive surface as scope="exam-corpus": public corpus/eb_*
|
||||||
logger.info("\n[Supabase] Clearing exam subsystem (storage + eb_*/exam_* tables)...")
|
# rows, cc.examboards storage, templates/layout/questions/boundaries/response
|
||||||
|
# areas, marking batches, submissions, and mark entries. (The legacy full reset
|
||||||
|
# cleared neither exam tables nor storage — folded in here.)
|
||||||
|
logger.info("\n[Supabase] Clearing entire exam-marker subsystem (public corpus, storage, templates/layout/questions/boundaries/response areas, marking batches, submissions, mark entries)...")
|
||||||
exam_storage = _clear_exam_storage()
|
exam_storage = _clear_exam_storage()
|
||||||
exam_cleared, exam_failed = _clear_tables(url, headers, EXAM_CORPUS_TABLES)
|
exam_cleared, exam_failed = _clear_tables(url, headers, EXAM_CORPUS_TABLES)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user