From c0775f3be1bcf794d421f4f2d20427f2c4347813 Mon Sep 17 00:00:00 2001 From: CC Worker Date: Sat, 6 Jun 2026 22:51:51 +0000 Subject: [PATCH] fix(exam): source-PDF upload uses shared cc.users bucket (S4-8.1 merge-gate fix) Pre-merge live smoke on .94 caught 'Bucket not found': the upload wrote to a per-institute bucket cc.institutes..private that isn't provisioned on dev. Use the shared SOURCE_BUCKET_FALLBACK (cc.users); institute is namespaced in the storage path + enforced by the files-row RLS. Per-institute buckets are a future multi-tenant concern. Catalogue path + cross-institute 404 already verified green. Co-Authored-By: Claude Opus 4.8 --- routers/exam/templates.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/routers/exam/templates.py b/routers/exam/templates.py index 4ea2f58..adaa931 100644 --- a/routers/exam/templates.py +++ b/routers/exam/templates.py @@ -167,8 +167,12 @@ async def _upload_template_source_file( file_id = str(uuid.uuid4()) safe_name = os.path.basename(upload.filename or "template.pdf") - bucket = f"cc.institutes.{institute_id}.private" if institute_id else SOURCE_BUCKET_FALLBACK - storage_path = f"exam-marker/{cabinet_id}/{file_id}/{safe_name}" + # Use the shared users bucket (exists on all envs). Per-institute private buckets + # (cc.institutes..private) are a future multi-tenant provisioning concern and are NOT + # created on dev .94 — using one here failed with "Bucket not found". The institute is already + # namespaced in the storage path + enforced by RLS on the files row. + bucket = SOURCE_BUCKET_FALLBACK + storage_path = f"exam-marker/{institute_id or 'noinst'}/{cabinet_id}/{file_id}/{safe_name}" try: storage.upload_file(bucket, storage_path, file_bytes, "application/pdf", upsert=True)