import os from modules.logger_tool import initialise_logger logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True) from modules.database.schemas.nodes.schools.schools import SchoolNode from modules.database.supabase.utils.client import SupabaseServiceRoleClient, CreateBucketOptions import modules.database.init.init_school_timetable as init_school_timetable import modules.database.tools.neontology_tools as neon def create_school_buckets(school_id: str, school_type: str, school_name: str, admin_access_token: str) -> dict: """Create storage buckets for a school Args: school_id: The unique identifier for the school school_type: The type of school (e.g., 'development') school_name: The display name of the school admin_access_token: The admin access token for Supabase operations Returns: Dictionary containing results of bucket creation operations """ logger.info(f"Creating storage buckets for school {school_name} ({school_type}/{school_id})") storage_client = SupabaseServiceRoleClient.for_admin(admin_access_token) base_path = f"cc.institutes.{school_type}.{school_id}" buckets = [ # Main school buckets { "id": f"{base_path}.public", "options": CreateBucketOptions( name=f"{school_type.title()} School Files - {school_name} - Public Files", public=True, file_size_limit=50 * 1024 * 1024, allowed_mime_types=[ 'image/*', 'video/*', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.*', 'text/plain', 'text/csv', 'application/json' ] ) }, { "id": f"{base_path}.private", "options": CreateBucketOptions( name=f"{school_type.title()} School Files - {school_name} - Private Files", public=False, file_size_limit=50 * 1024 * 1024, allowed_mime_types=[ 'image/*', 'video/*', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.*', 'text/plain', 'text/csv', 'application/json' ] ) }, # Curriculum buckets { "id": f"{base_path}.curriculum.public", "options": CreateBucketOptions( name=f"{school_type.title()} School Files - {school_name} - Curriculum Public Files", public=True, file_size_limit=50 * 1024 * 1024, allowed_mime_types=[ 'image/*', 'video/*', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.*', 'text/plain', 'text/csv', 'application/json' ] ) }, { "id": f"{base_path}.curriculum.private", "options": CreateBucketOptions( name=f"{school_type.title()} School Files - {school_name} - Curriculum Private Files", public=False, file_size_limit=50 * 1024 * 1024, allowed_mime_types=[ 'image/*', 'video/*', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.*', 'text/plain', 'text/csv', 'application/json' ] ) } ] results = {} for bucket in buckets: try: result = storage_client.create_bucket(bucket["id"], bucket["options"]) results[bucket["id"]] = { "status": "success", "result": result } logger.info(f"Successfully created bucket {bucket['id']}") except Exception as e: logger.error(f"Error creating school bucket {bucket['id']}: {str(e)}") results[bucket["id"]] = { "status": "error", "error": str(e) } return results def create_school(db_name: str, id: str, name: str, website: str, school_type: str, is_public: bool = True, school_node: SchoolNode | None = None, dataframes=None): if not name or not id or not website or not school_type: logger.error("School name, id, website and school_type are required to create a school.") raise ValueError("School name, id, website and school_type are required to create a school.") logger.info(f"Initialising neo4j connection...") neon.init_neontology_connection() # Create School Node if not provided if not school_node: if is_public: school_node = SchoolNode( unique_id=f'School_{id}', tldraw_snapshot="", id=id, name=name, website=website, school_type=school_type ) else: # Create private school node with default values school_node = SchoolNode( unique_id=f'School_{id}', tldraw_snapshot="", id=id, name=name, website=website, school_type=school_type, establishment_number="0000", establishment_name=name, establishment_type="Default", establishment_status="Open", phase_of_education="All", statutory_low_age=11, statutory_high_age=18, school_capacity=1000 ) # First create/merge the school node in the main cc.institutes database logger.info(f"Creating school node in main cc.institutes database...") neon.create_or_merge_neontology_node(school_node, database="cc.institutes", operation='merge') # Then create/merge the school node in the specific school database logger.info(f"Creating school node in specific database {db_name}...") neon.create_or_merge_neontology_node(school_node, database=db_name, operation='merge') school_nodes = { 'school_node': school_node, 'db_name': db_name } if dataframes is not None: logger.info(f"Creating school timetable for {name} with {len(dataframes)} dataframes...") school_timetable_nodes = init_school_timetable.create_school_timetable(dataframes, db_name, school_node) school_nodes['school_timetable_nodes'] = school_timetable_nodes else: logger.warning(f"No dataframes provided for {name}, skipping school timetable...") logger.info(f"School {name} created successfully...") return school_nodes